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

Marcelo Póvoa marspeoplester at gmail.com
Wed Jul 21 05:16:28 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  958f5f8c6f85ce8db4f9b583070804d9a019bd46 (commit)
       via  31a3641e4876dfb07633068be482ed1c140808a6 (commit)
      from  ef5497e0213b4143f745be78fdd2dfc3579dee8c (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 958f5f8c6f85ce8db4f9b583070804d9a019bd46
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date:   Wed Jul 21 00:15:59 2010 -0300

    Begin high band generation by its excitation gain
    calculation

diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index 42d5655..29624fa 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -60,7 +60,7 @@ typedef struct {
     uint16_t adap;                         ///< adaptive codebook index
     uint16_t ltp;                          ///< ltp-filtering flag
     uint16_t vq_gain;                      ///< VQ adaptive and innovative gains
-    uint16_t energy;                       ///< high-band energy
+    uint16_t hb_gain;                      ///< high-band energy index (mode 23k85 only)
     uint16_t pul_ih[4];                    ///< MSBs part of codebook index (high modes only)
     uint16_t pul_il[4];                    ///< LSBs part of codebook index
 } AMRWBSubFrame;
@@ -597,7 +597,7 @@ static const uint16_t order_MODE_23k85[] = {
     11, AMR_OF(0, pul_il[3]), 234, 192, 358, 448, 260, 239, 268, 373,
                               401, 428, 473,
      7,   AMR_OF(0, vq_gain),   3,  20,  42,  28,  32,  38,  24,
-     4,    AMR_OF(0, energy),  72,  73,  74,  75,
+     4,   AMR_OF(0, hb_gain),  72,  73,  74,  75,
      6,      AMR_OF(1, adap),  36,  49,  88,  93,  99, 114,
      1,       AMR_OF(1, ltp), 122,
     11, AMR_OF(1, pul_ih[0]), 132, 155, 153, 182, 241, 308, 360, 252,
@@ -617,7 +617,7 @@ static const uint16_t order_MODE_23k85[] = {
     11, AMR_OF(1, pul_il[3]), 246, 215, 368, 451, 269, 277, 309, 402,
                               423, 435, 471,
      7,   AMR_OF(1, vq_gain),   4,  21,  43,  29,  33,  39,  25,
-     4,    AMR_OF(1, energy),  76,  77,  78,  79,
+     4,   AMR_OF(1, hb_gain),  76,  77,  78,  79,
      9,      AMR_OF(2, adap),  15,  16,  17,  18,  19,  51,  70,  96,
                               108,
      1,       AMR_OF(2, ltp), 123,
@@ -638,7 +638,7 @@ static const uint16_t order_MODE_23k85[] = {
     11, AMR_OF(2, pul_il[3]), 303, 205, 399, 450, 283, 275, 264, 379,
                               425, 438, 462,
      7,   AMR_OF(2, vq_gain),   5,  22,  44,  30,  34,  40,  26,
-     4,    AMR_OF(2, energy),  80,  81,  82,  83,
+     4,   AMR_OF(2, hb_gain),  80,  81,  82,  83,
      6,      AMR_OF(3, adap),  37,  50,  89,  94, 100, 115,
      1,       AMR_OF(3, ltp), 124,
     11, AMR_OF(3, pul_ih[0]), 135, 168, 152, 179, 226, 302, 347, 299,
@@ -658,7 +658,7 @@ static const uint16_t order_MODE_23k85[] = {
     11, AMR_OF(3, pul_il[3]), 255, 183, 389, 449, 244, 281, 305, 394,
                               405, 434, 460,
      7,   AMR_OF(3, vq_gain),   6,  23,  45,  31,  35,  41,  27,
-     4,    AMR_OF(3, energy),  84,  85,  86,  87,
+     4,   AMR_OF(3, hb_gain),  84,  85,  86,  87,
      0
 };
 
@@ -1792,12 +1792,23 @@ static const float *ir_filters_lookup[2] = {
     ir_filter_str, ir_filter_mid
 };
 
-/* High-pass filter coefficients for inputs and outputs (feedback) */
-static const float hpf_x_coef[3] = {
-    0.989501953, -1.979003906, 0.989501953
+/* High-pass filters coefficients for inputs and outputs (feedback) */
+
+static const float hpf_31_coef[2][3] = {        //  31 kHz cutoff filter
+    { 0.989501953, -1.979003906, 0.989501953 },
+    { 1.978881836, -0.979125977, 0           }
+};
+
+static const float hpf_400_coef[2][3] = {       // 400 kHz cutoff filter
+    { 0.893554687, -1.787109375, 0.893554687 },
+    { 1.787109375, -0.864257812, 0           }
 };
 
-static const float hpf_y_coef[2] = { 1.978881836, -0.979125977 };
+/* High band quantized gains for 23k85 in Q14 */
+static const uint16_t qua_hb_gain[16] = {
+   3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264,
+   11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728
+};
 
 /* Core frame sizes in each mode */
 static const uint16_t cf_sizes_wb[] = {
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index dac45d3..2fcc61a 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -950,12 +950,14 @@ static void de_emphasis(float *synth, float m, float mem[1])
  * with cutoff frequency at 31 Hz
  *
  * @param out                 [out] buffer for filtered output
+ * @param hpf_coef            [in] filter coefficients as used below
  * @param mem                 [in] state from last filtering
  * @param in                  [in] input speech data
  *
  * @remark It is safe to pass the same array in in and out parameters.
  */
-static void high_pass_filter(float *out, float mem[4], const float *in)
+static void high_pass_filter(float *out, const float hpf_coef[2][3],
+                             float mem[4], const float *in)
 {
     int i;
     float *x = mem - 1, *y = mem + 2; // previous inputs and outputs
@@ -963,9 +965,9 @@ static void high_pass_filter(float *out, float mem[4], const float *in)
     for (i = 0; i < AMRWB_SUBFRAME_SIZE; i++) {
         float x0 = in[i];
 
-        out[i] = hpf_x_coef[0] * x0   + hpf_y_coef[0] * y[0] +
-                 hpf_x_coef[1] * x[1] + hpf_y_coef[1] * y[1] +
-                 hpf_x_coef[2] * x[2];
+        out[i] = hpf_coef[0][0] * x0   + hpf_coef[1][0] * y[0] +
+                 hpf_coef[0][1] * x[1] + hpf_coef[1][1] * y[1] +
+                 hpf_coef[0][2] * x[2];
 
         y[1] = y[0];
         y[0] = out[i];
@@ -976,6 +978,31 @@ static void high_pass_filter(float *out, float mem[4], const float *in)
 }
 
 /**
+ * Calculate the high band gain based on encoded index (23k85 mode) or
+ * on the lower band speech signal and the Voice Activity Detection flag
+ *
+ * @param ctx                 [in] the context
+ * @param synth               [in] LB speech synthesis at 12.8k
+ * @param hb_idx              [in] gain index for mode 23k85 only
+ * @param vad                 [in] VAD flag for the frame
+ */
+static float find_hb_gain(AMRWBContext *ctx, const float *synth,
+                          uint16_t hb_idx, uint8_t vad)
+{
+    int wsp = (vad > 0 ? 1 : 0);
+    float tilt;
+
+    if (ctx->fr_cur_mode == MODE_23k85)
+        return qua_hb_gain[hb_idx] / (float) (1 << 14);
+
+    tilt = ff_dot_productf(synth, synth + 1, AMRWB_SUBFRAME_SIZE - 1) /
+           ff_dot_productf(synth, synth, AMRWB_SUBFRAME_SIZE);
+
+    /* return gain bounded by [0.1, 1.0] */
+    return FFMAX(0.1, FFMIN(1.0, (1.0 - tilt) * (1.25 - 0.25 * wsp)));
+}
+
+/**
  * Update context state before the next subframe
  */
 static void update_sub_state(AMRWBContext *ctx)
@@ -997,6 +1024,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     float *synth_fixed_vector;               // pointer to the fixed vector that synthesis should use
     float synth_fixed_gain;                  // the fixed gain that synthesis should use
     float voice_fac, stab_fac;               // parameters used for gain smoothing
+    float hb_gain;
     int sub, i;
 
     ctx->fr_cur_mode = unpack_bitstream(ctx, buf, buf_size);
@@ -1085,8 +1113,18 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
         /* Synthesis speech post-processing */
         de_emphasis(&ctx->samples_in[LP_ORDER], PREEMPH_FAC, ctx->demph_mem);
 
-        high_pass_filter(&ctx->samples_in[LP_ORDER], ctx->hpf_mem,
-                         &ctx->samples_in[LP_ORDER]);
+        high_pass_filter(&ctx->samples_in[LP_ORDER], hpf_31_coef,
+                         ctx->hpf_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]);
+
+        hb_gain = find_hb_gain(ctx, &ctx->samples_in[LP_ORDER],
+                               cur_subframe->hb_gain, cf->vad);
 
         /* Update buffers and history */
         ff_clear_fixed_vector(ctx->fixed_vector, &fixed_sparse,

commit 31a3641e4876dfb07633068be482ed1c140808a6
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date:   Tue Jul 20 02:03:21 2010 -0300

    Fix the direct variable indexing inside (sub)frame

diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index 779fa70..42d5655 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -54,17 +54,19 @@ enum Mode {
     NO_DATA                                ///< no transmission
 };
 
+/* All decoded parameters in these structs must be 2 bytes long
+ * because of the direct indexing at the frame parsing */
 typedef struct {
     uint16_t adap;                         ///< adaptive codebook index
-    uint8_t ltp;                           ///< ltp-filtering flag
-    uint8_t vq_gain;                       ///< VQ adaptive and innovative gains
-    uint8_t energy;                        ///< high-band energy
+    uint16_t ltp;                          ///< ltp-filtering flag
+    uint16_t vq_gain;                      ///< VQ adaptive and innovative gains
+    uint16_t energy;                       ///< high-band energy
     uint16_t pul_ih[4];                    ///< MSBs part of codebook index (high modes only)
     uint16_t pul_il[4];                    ///< LSBs part of codebook index
 } AMRWBSubFrame;
 
 typedef struct {
-    uint8_t vad;                           ///< voice activity detection flag
+    uint16_t vad;                          ///< voice activity detection flag
     uint16_t isp_id[7];                    ///< index of ISP subvectors
     AMRWBSubFrame subframe[4];             ///< data for subframes
 } AMRWBFrame;
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index b1f2cc2..dac45d3 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -124,7 +124,7 @@ static enum Mode unpack_bitstream(AMRWBContext *ctx, const uint8_t *buf,
 
     // XXX: We are using only the "MIME/storage" format
     // used by libopencore. This format is simpler and
-    // do not have the auxiliary information of the frame
+    // does not have the auxiliary information of the frame
 
     /* AMR-WB Auxiliary Information */
     /*

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

Summary of changes:
 libavcodec/amrwbdata.h |   37 +++++++++++++++++++++++-----------
 libavcodec/amrwbdec.c  |   52 +++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 70 insertions(+), 19 deletions(-)


hooks/post-receive
-- 
AMR-WB decoder


More information about the FFmpeg-soc mailing list