[FFmpeg-soc] G.723.1 Encoder: Compute combined impulse and zero response

Mohamed Naufal naufal11 at gmail.com
Tue Aug 17 23:08:49 CEST 2010


 libavcodec/g723_1.c |   93 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index 994fecb..d71fa60 100755
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -59,6 +59,9 @@ typedef struct g723_1_context {
                                  ///< gain scaling unit memory
     int16_t prev_data[HALF_FRAME_LEN];
     int16_t prev_weight_sig[PITCH_MAX];
+
+    int16_t perf_fir_mem[LPC_ORDER];       ///< perceptual filter fir
+    int16_t perf_iir_mem[LPC_ORDER];       ///< and iir memories
 } G723_1_Context;

 static av_cold int g723_1_decode_init(AVCodecContext *avctx)
@@ -1594,6 +1597,63 @@ static void harmonic_filter(HFParam *hf,
int16_t *src, int16_t *dest)
     }
 }

+/**
+ * Perform harmonic noise shaping.
+ *
+ * @param hf filter parameters
+ */
+static void harmonic_noise_sub(HFParam *hf, int16_t *src, int16_t *dest)
+{
+    int i;
+
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t temp = hf->gain * src[i - hf->index] << 1;
+        dest[i] = av_clipl_int32(((dest[i] - src[i]) << 16) - temp +
+                                 (1 << 15)) >> 16;
+    }
+}
+/**
+ * Combined synthesis and formant perceptual weighting filer.
+ *
+ * @param qnt_lpc  quantized lpc coefficients
+ * @param perf_lpc perceptual filter coefficients
+ * @param perf_fir perceptual filter fir memory
+ * @param perf_iir perceptual filter iir memory
+ * @param scale    the filter output will be scaled by 2^scale
+ */
+static void synth_percept_filter(int16_t *qnt_lpc, int16_t *perf_lpc,
+                                 int16_t *perf_fir, int16_t *perf_iir,
+                                 int16_t *src, int16_t *dest, int scale)
+{
+    int i, j;
+    int16_t buf_16[SUBFRAME_LEN + LPC_ORDER];
+    int buf[SUBFRAME_LEN];
+
+    int16_t *bptr_16 = buf_16 + LPC_ORDER;
+
+    memcpy(buf_16, perf_fir, sizeof(int16_t) * LPC_ORDER);
+    memcpy(dest - LPC_ORDER, perf_iir, sizeof(int16_t) * LPC_ORDER);
+
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t temp = 0;
+        for (j = 1; j <= LPC_ORDER; j++)
+            temp -= qnt_lpc[j - 1] * bptr_16[i - j];
+
+        buf[i]    = (src[i] << 15) + (temp << 3);
+        bptr_16[i] = av_clipl_int32((int64_t)buf[i] + (1 << 15)) >> 16;
+    }
+
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t fir = 0, iir = 0;
+        for (j = 1; j <= LPC_ORDER; j++) {
+            fir -= perf_lpc[j - 1] * bptr_16[i - j];
+            iir += perf_lpc[j + LPC_ORDER - 1] * dest[i - j];
+        }
+        dest[i] = av_clipl_int32(((buf[i] + (fir << 3)) << scale) +
(iir << 3) +
+                                 (1<<15)) >> 16;
+    }
+}
+
 static int g723_1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
                                int buf_size, void *data)
 {
@@ -1601,10 +1661,12 @@ static int g723_1_encode_frame(AVCodecContext
*avctx, unsigned char *buf,
     HFParam hf[4];
     int16_t unq_lpc[LPC_ORDER * SUBFRAMES];
     int16_t cur_lsp[LPC_ORDER];
+    int16_t qnt_lpc[LPC_ORDER * SUBFRAMES];
     int16_t weighted_lpc[LPC_ORDER * SUBFRAMES << 1];
     int16_t vector[FRAME_LEN + PITCH_MAX];

     int16_t *in = data;
+    int offset = 0;
     int i, j;

     highpass_filter(in, &p->fir_mem[0], &p->iir_mem[0]);
@@ -1647,6 +1709,37 @@ static int g723_1_encode_frame(AVCodecContext
*avctx, unsigned char *buf,

     memcpy(p->prev_lsp, cur_lsp, sizeof(int16_t) * LPC_ORDER);

+    offset = 0;
+    for (i = 0; i < SUBFRAMES; i++) {
+        int16_t impulse_resp[SUBFRAME_LEN];
+        int16_t flt_in[SUBFRAME_LEN];
+        int16_t zero[LPC_ORDER];
+
+        /**
+         * Compute the combined impulse response of the synthesis filter,
+         * formant perceptual weighting filter and harmonic noise
shaping filter
+         */
+        memset(zero, 0, sizeof(int16_t) * LPC_ORDER);
+        memset(vector, 0, sizeof(int16_t) * PITCH_MAX);
+        memset(flt_in, 0, sizeof(int16_t) * SUBFRAME_LEN);
+
+        flt_in[0] = 1 << 13;  /* Unit impulse */
+        synth_percept_filter(qnt_lpc + offset, weighted_lpc + offset,
+                             zero, zero, flt_in, vector + PITCH_MAX, 1);
+        harmonic_filter(hf + i, vector + PITCH_MAX, impulse_resp);
+
+         /* Compute the combined zero input response */
+        memset(vector, 0, sizeof(int16_t) * PITCH_MAX);
+
+        synth_percept_filter(qnt_lpc + offset, weighted_lpc + offset,
+                             p->perf_fir_mem, p->perf_iir_mem,
+                             zero, vector + PITCH_MAX, 0);
+        harmonic_noise_sub(hf + i, vector + PITCH_MAX, in);
+
+        offset += LPC_ORDER;
+        in += SUBFRAME_LEN;
+    }
+
     return 0;
 }

--


More information about the FFmpeg-soc mailing list