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

Marcelo Póvoa marspeoplester at gmail.com
Fri Jul 30 07:35:21 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  121492a18969d4665210fe6dede43482776acce8 (commit)
       via  8cbd44b44a1b8d4332fc8d22ced69a93d85a31fc (commit)
      from  01100290fe3b220e4fbbe6ec16f7f85652d25092 (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 121492a18969d4665210fe6dede43482776acce8
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date:   Fri Jul 30 02:34:33 2010 -0300

    Write post-processing FIR filters for the high-band

diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index 76a1a60..17f7d9e 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -28,6 +28,7 @@
 #define LP_ORDER_16k          20               ///< lpc filter order at 16kHz
 #define UPS_FIR_SIZE          12               ///< upsampling filter size
 #define UPS_MEM_SIZE          2 * UPS_FIR_SIZE
+#define HB_FIR_SIZE           30               ///< amount of past data needed by HB filters
 
 #define MIN_ISF_SPACING       (128 / 32768.0)  ///< minimum isf gap
 #define PRED_FACTOR           (1.0 / 3.0)
@@ -1840,6 +1841,36 @@ static const uint16_t qua_hb_gain[16] = {
    11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728
 };
 
+/* High-band post-processing FIR filters coefficients in Q15 */
+// XXX: not sure if it is Q15 indeed (guessing)
+static const float bpf_6_7_coef[31] = { // band pass, 6kHz and 7kHz cutoffs
+    -9.765625e-04,  1.434326e-03,  9.765625e-04,
+    -8.239746e-04, -1.126099e-02,  3.424072e-02,
+    -4.336548e-02,  0.000000e+00,  1.159058e-01,
+    -2.709961e-01,  3.768616e-01, -3.352051e-01,
+     1.082764e-01,  2.369995e-01, -5.493469e-01,
+     6.749878e-01,
+    -5.493469e-01,  2.369995e-01,  1.082764e-01,
+    -3.352051e-01,  3.768616e-01, -2.709961e-01,
+     1.159058e-01,  0.000000e+00, -4.336548e-02,
+     3.424072e-02, -1.126099e-02, -8.239746e-04,
+     9.765625e-04,  1.434326e-03, -9.765625e-04
+};
+
+static const float lpf_7_coef[31] = { // low pass, 7kHz cutoff
+    -6.408691e-04,  1.434326e-03, -2.716064e-03,
+     4.455566e-03, -6.195068e-03,  6.988525e-03,
+    -5.401611e-03,  0.000000e+00,  1.022339e-02,
+    -2.560425e-02,  4.531860e-02, -6.747437e-02,
+     8.944702e-02, -1.080933e-01,  1.206360e-01,
+     8.753052e-01,
+     1.206360e-01, -1.080933e-01,  8.944702e-02,
+    -6.747437e-02,  4.531860e-02, -2.560425e-02,
+     1.022339e-02,  0.000000e+00, -5.401611e-03,
+     6.988525e-03, -6.195068e-03,  4.455566e-03,
+    -2.716064e-03,  1.434326e-03, -6.408691e-04
+};
+
 /* Core frame sizes in each mode */
 static const uint16_t cf_sizes_wb[] = {
     132, 177, 253, 285, 317, 365, 397, 461, 477,
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 2786816..de4b399 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -73,11 +73,13 @@ typedef struct {
     float                           prev_tr_gain; ///< previous initial gain used by noise enhancer for thresold
 
     float samples_az[LP_ORDER + AMRWB_SUBFRAME_SIZE]; ///< lower band samples from synthesis at 12.8kHz
-    float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling at 12.8kHz
+    float samples_up[UPS_MEM_SIZE + AMRWB_SUBFRAME_SIZE]; ///< lower band samples processed for upsampling
     float samples_hb[LP_ORDER_16k + AMRWB_SFR_SIZE_OUT]; ///< higher band samples from synthesis at 16kHz
 
-    float          hpf_31_mem[4], hpf_400_mem[4]; ///< previous values in the high-pass filters
+    float          hpf_31_mem[4], hpf_400_mem[4]; ///< previous values in the high pass filters
     float                           demph_mem[1]; ///< previous value in the de-emphasis filter
+    float               bpf_6_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band band pass filter
+    float                 lpf_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band low pass filter
 
     AVLFG                                   prng; ///< random number generator for white noise excitation
     uint8_t                          first_frame; ///< flag active during decoding of the first frame
@@ -1176,6 +1178,39 @@ static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,
 }
 
 /**
+ * Apply to high-band samples a 15th order filter
+ * The filter characteristic depends on the given coefficients
+ *
+ * @param out                 [out] buffer for filtered output
+ * @param fir_coef            [in] filter coefficients
+ * @param mem                 [in/out] state from last filtering (updated)
+ * @param cp_gain             [in] compensation gain (usually the filter gain)
+ * @param in                  [in] input speech data (high-band)
+ *
+ * @remark It is safe to pass the same array in in and out parameters.
+ */
+static void hb_fir_filter(float *out, const float fir_coef[HB_FIR_SIZE + 1],
+                          float mem[HB_FIR_SIZE], float cp_gain, const float *in)
+{
+    int i, j;
+    float data[AMRWB_SFR_SIZE_OUT + HB_FIR_SIZE]; // past and current samples
+
+    memcpy(data, mem, HB_FIR_SIZE * sizeof(float));
+
+    for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++)
+        data[i + HB_FIR_SIZE] = in[i] / cp_gain;
+
+    for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++)
+    {
+        out[i] = 0.0;
+        for (j = 0; j <= HB_FIR_SIZE; j++)
+            out[i] += data[i + j] * fir_coef[j];
+    }
+
+    memcpy(mem, data + AMRWB_SFR_SIZE_OUT, HB_FIR_SIZE * sizeof(float));
+}
+
+/**
  * Update context state before the next subframe
  */
 static void update_sub_state(AMRWBContext *ctx)
@@ -1212,6 +1247,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     float voice_fac, stab_fac;               // parameters used for gain smoothing
     float synth_exc[AMRWB_SUBFRAME_SIZE];    // post-processed excitation for synthesis
     float hb_exc[AMRWB_SFR_SIZE_OUT];        // excitation for the high frequency band
+    float hb_samples[AMRWB_SFR_SIZE_OUT];    // filtered high-band samples from synthesis
     float hb_gain;
     int sub, i;
 
@@ -1324,12 +1360,17 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                      hb_exc, ctx->isf_cur, ctx->isf_past_final);
 
         /* High-band post-processing filters */
+        hb_fir_filter(hb_samples, bpf_6_7_coef, ctx->bpf_6_7_mem,
+                      4.0, &ctx->samples_hb[LP_ORDER_16k]);
+
+        if (ctx->fr_cur_mode == MODE_23k85)
+            hb_fir_filter(hb_samples, lpf_7_coef, ctx->lpf_7_mem,
+                          1.0, hb_samples);
 
         /* Add low frequency and high frequency bands */
         for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++) {
             // XXX: the lower band should really be upscaled by 2.0?
-            sub_buf[i] = (sub_buf[i] * 2.0 +
-                          ctx->samples_hb[i + LP_ORDER_16k]) / 32768.0;
+            sub_buf[i] = (sub_buf[i] * 2.0 + hb_samples[i]) / 32768.0;
         }
 
         /* Update buffers and history */

commit 8cbd44b44a1b8d4332fc8d22ced69a93d85a31fc
Author: Marcelo Povoa <marspeoplester at gmail.com>
Date:   Fri Jul 30 02:32:08 2010 -0300

    Fix high-band excitation length

diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 7f6152f..2786816 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -931,11 +931,10 @@ static void de_emphasis(float *out, float *in, float m, float mem[1])
 
 /**
  * Apply to synthesis a 2nd order high-pass filter
- * 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 mem                 [in/out] state from last filtering (updated)
  * @param in                  [in] input speech data
  *
  * @remark It is safe to pass the same array in in and out parameters.
@@ -1028,13 +1027,13 @@ static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
     float energy = ff_dot_productf(synth_exc, synth_exc, AMRWB_SUBFRAME_SIZE);
 
     /* Generate a white-noise excitation */
-    for (i = 0; i < AMRWB_SUBFRAME_SIZE; i++)
+    for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++)
         hb_exc[i] = 32768.0 - (uint16_t) av_lfg_get(&ctx->prng);
 
     ff_scale_vector_to_given_sum_of_squares(hb_exc, hb_exc, energy,
-                                            AMRWB_SUBFRAME_SIZE);
+                                            AMRWB_SFR_SIZE_OUT);
 
-    for (i = 0; i < AMRWB_SUBFRAME_SIZE; i++)
+    for (i = 0; i < AMRWB_SFR_SIZE_OUT; i++)
         hb_exc[i] *= hb_gain;
 }
 
@@ -1212,7 +1211,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     float synth_fixed_gain;                  // the fixed gain that synthesis should use
     float voice_fac, stab_fac;               // parameters used for gain smoothing
     float synth_exc[AMRWB_SUBFRAME_SIZE];    // post-processed excitation for synthesis
-    float hb_exc[AMRWB_SUBFRAME_SIZE];       // excitation for the high frequency band
+    float hb_exc[AMRWB_SFR_SIZE_OUT];        // excitation for the high frequency band
     float hb_gain;
     int sub, i;
 

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

Summary of changes:
 libavcodec/amrwbdata.h |   31 ++++++++++++++++++++++++
 libavcodec/amrwbdec.c  |   60 ++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 81 insertions(+), 10 deletions(-)


hooks/post-receive
-- 
AMR-WB decoder


More information about the FFmpeg-soc mailing list