[FFmpeg-soc] [soc] G.723.1 Decoder a7b84565a34cc81ceb2d60bc871a95eaafea6474
naufal11 at gmail.com
naufal11 at gmail.com
Mon Jul 26 17:15:08 CEST 2010
- Log -----------------------------------------------------------------
commit a7b84565a34cc81ceb2d60bc871a95eaafea6474
Author: Naufal <naufal11 at gmail.com>
Date: Mon Jul 26 20:41:09 2010 +0530
Add formant postfilter
diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index 68653e5..f15860f 100755
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -23,6 +23,10 @@ typedef struct g723_1_context {
int16_t interp_gain;
int16_t sid_gain;
int16_t cur_gain;
+
+ int16_t reflection_coef;
+ int16_t pf_fir_mem[LPC_ORDER]; ///< Formant FIR postfilter memory
+ int pf_iir_mem[LPC_ORDER]; ///< Formant IIR postfilter memory
} G723_1_Context;
static av_cold int g723_1_decode_init(AVCodecContext *avctx)
@@ -686,6 +690,93 @@ static void residual_interp(int16_t *buf, int16_t *out, int16_t lag,
}
}
+/*
+ * @param filter_coef filter coefficients vector
+ * @param src input signal vector
+ * @param dest output filtered vector
+ */
+static void iir_filter(int16_t filter_coef[][LPC_ORDER], int16_t *src,
+ int *dest)
+{
+ int i, j;
+
+ for (i = 0; i < SUBFRAME_LEN; i++) {
+ int64_t filter = 0;
+
+ for (j = 1; j <= LPC_ORDER; j++) {
+ filter -= filter_coef[0][j - 1] * src[i - j] -
+ filter_coef[1][j - 1] * (dest[i - j] >> 16);
+ }
+
+ dest[i] = av_clipl_int32((src[i] << 16) + (filter << 3) + (1 << 15));
+ }
+}
+
+/*
+ * @param buf synthesized speech vector
+ * @param lpc quantized lpc coefficients
+ */
+static int formant_postfilter(G723_1_Context *p, int16_t *buf, int16_t *lpc)
+{
+ int16_t filter_coef[2][LPC_ORDER];
+ int filter_signal[LPC_ORDER+SUBFRAME_LEN];
+ int16_t temp_vector[SUBFRAME_LEN];
+ int auto_corr[2];
+ int16_t temp;
+ int scale, energy;
+ int i;
+
+ // Compute FIR and IIR filter coefficients
+ for (i=0; i<LPC_ORDER; i++) {
+ filter_coef[0][i] = (-lpc[i] * postfilter_tbl[0][i] + (1<<14)) >> 15;
+ filter_coef[1][i] = (-lpc[i] * postfilter_tbl[1][i] + (1<<14)) >> 15;
+ }
+
+ // Normalize
+ memcpy(temp_vector, buf, SUBFRAME_LEN * sizeof(int16_t));
+ scale = scale_vector(temp_vector, SUBFRAME_LEN);
+
+ // Compute auto correlation coefficients
+ auto_corr[0] = dot_product(temp_vector, temp_vector + 1, SUBFRAME_LEN - 1);
+ auto_corr[1] = dot_product(temp_vector, temp_vector, SUBFRAME_LEN);
+
+ // Compute normalized signal energy
+ temp = 2 * scale + 4;
+ if (temp < 0)
+ energy = av_clipl_int32((int64_t)auto_corr[1] << -temp);
+ else
+ energy = auto_corr[1] >> temp;
+
+ // Compute reflection coefficient
+ temp = auto_corr[1] >> 16;
+ if (temp) {
+ temp = (auto_corr[0]>>2) / temp;
+ }
+
+ p->reflection_coef = ((p->reflection_coef << 2) - p->reflection_coef +
+ temp + 2) >> 2;
+
+ memcpy(buf - LPC_ORDER, p->pf_fir_mem, LPC_ORDER * sizeof(int16_t));
+ memcpy(filter_signal, p->pf_iir_mem, LPC_ORDER * sizeof(int));
+
+ iir_filter(filter_coef, buf, filter_signal + LPC_ORDER);
+
+ memcpy(p->pf_fir_mem, buf + SUBFRAME_LEN - LPC_ORDER, LPC_ORDER *
+ sizeof(int16_t));
+ memcpy(p->pf_iir_mem, filter_signal + SUBFRAME_LEN, LPC_ORDER *
+ sizeof(int));
+
+ // Compensation filter
+ temp = (p->reflection_coef * 0xffffc000 >> 15) & 0xfffc;
+ for (i = 0; i < SUBFRAME_LEN; i++) {
+ buf[i] = av_clipl_int32(filter_signal[LPC_ORDER + i] +
+ (((filter_signal[LPC_ORDER + i - 1] >> 16) *
+ temp) << 1)) >> 16;
+ }
+
+ return energy;
+}
+
static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
int *data_size, AVPacket *avpkt)
{
@@ -700,6 +791,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
int16_t excitation[FRAME_LEN + PITCH_MAX];
int16_t acb_vector[SUBFRAME_LEN];
int16_t *vector_ptr;
+ int energy;
int bad_frame = 0, i, j;
if (!buf_size || buf_size < frame_size[buf[0] & 3]) {
@@ -794,6 +886,8 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
// Store the last 10 values of the output vector
memcpy(p->filter_mem, vector_ptr + SUBFRAME_LEN - LPC_ORDER,
LPC_ORDER * sizeof(int16_t));
+ energy = formant_postfilter(p, vector_ptr,
+ &lpc[i * (LPC_ORDER + 1) + 1]);
vector_ptr += SUBFRAME_LEN;
}
diff --git a/libavcodec/g723_1_data.h b/libavcodec/g723_1_data.h
index 411e23c..ec93acf 100644
--- a/libavcodec/g723_1_data.h
+++ b/libavcodec/g723_1_data.h
@@ -1206,3 +1206,13 @@ static const int16_t adaptive_cb_gain170[170 * 20] = {
6538, -1712, -4280, -4804, -3613, -2609, -2707, -2868,
-4534, -2487, -3932, -4166, -2113, -3341, -3540, -3070
};
+
+/*
+ * 0.65^i (FIR) and 0.75^i (IIR) scaled by 2^15
+ */
+static const int16_t postfilter_tbl[2][LPC_ORDER] = {
+ // Zero part
+ {21299, 13844, 8999, 5849, 3802, 2471, 1606, 1044, 679, 441},
+ // Pole part
+ {24576, 18432, 13824, 10368, 7776, 5832, 4374, 3281, 2460, 1845}
+};
-----------------------------------------------------------------------
Summary of changes:
libavcodec/g723_1.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
libavcodec/g723_1_data.h | 10 +++++
2 files changed, 104 insertions(+), 0 deletions(-)
--
http://github.com/naufal/ffmpeg-soc
More information about the FFmpeg-soc
mailing list