[FFmpeg-cvslog] G.723.1 demuxer and decoder

Mohamed Naufal Basheer git at videolan.org
Sun Jul 22 22:22:51 CEST 2012


ffmpeg | branch: master | Mohamed Naufal Basheer <naufal11 at gmail.com> | Thu Mar 17 23:56:50 2011 +0100| [55c3a4f617171ad1138df684cbafa570807bc6a9] | committer: Kostya Shishkov

G.723.1 demuxer and decoder

Signed-off-by: Kostya Shishkov <kostya.shishkov at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=55c3a4f617171ad1138df684cbafa570807bc6a9
---

 Changelog                |    1 +
 doc/general.texi         |    1 +
 libavcodec/Makefile      |    2 +
 libavcodec/allcodecs.c   |    1 +
 libavcodec/g723_1.c      | 1175 +++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/g723_1_data.h | 1194 ++++++++++++++++++++++++++++++++++++++++++++++
 libavformat/Makefile     |    1 +
 libavformat/allformats.c |    1 +
 libavformat/g723_1.c     |   85 ++++
 libavformat/rtp.c        |    2 +-
 10 files changed, 2462 insertions(+), 1 deletion(-)

diff --git a/Changelog b/Changelog
index b6be51a..3d13254 100644
--- a/Changelog
+++ b/Changelog
@@ -38,6 +38,7 @@ version <next>:
 - RTMPS protocol support
 - RTMPTS protocol support
 - JPEG 2000 encoding support through OpenJPEG
+- G.723.1 demuxer and decoder
 
 
 version 0.8:
diff --git a/doc/general.texi b/doc/general.texi
index 38916de..f5c6293 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -730,6 +730,7 @@ following image formats are supported:
 @item DV audio               @tab     @tab  X
 @item Enhanced AC-3          @tab  X  @tab  X
 @item FLAC (Free Lossless Audio Codec)  @tab  X  @tab  IX
+ at item G.723.1                @tab     @tab  X
 @item GSM                    @tab  E  @tab  X
     @tab encoding supported through external library libgsm
 @item GSM Microsoft variant  @tab  E  @tab  X
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index c0a2756..b65e249 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -168,6 +168,8 @@ OBJS-$(CONFIG_FLIC_DECODER)            += flicvideo.o
 OBJS-$(CONFIG_FOURXM_DECODER)          += 4xm.o
 OBJS-$(CONFIG_FRAPS_DECODER)           += fraps.o
 OBJS-$(CONFIG_FRWU_DECODER)            += frwu.o
+OBJS-$(CONFIG_G723_1_DECODER)          += g723_1.o acelp_vectors.o \
+                                          celp_filters.o celp_math.o
 OBJS-$(CONFIG_GIF_DECODER)             += gifdec.o lzw.o
 OBJS-$(CONFIG_GIF_ENCODER)             += gif.o lzwenc.o
 OBJS-$(CONFIG_GSM_DECODER)             += gsmdec.o gsmdec_data.o msgsmdec.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index be67020..7e7cee6 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -262,6 +262,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
     REGISTER_ENCDEC  (EAC3, eac3);
     REGISTER_ENCDEC  (FLAC, flac);
+    REGISTER_DECODER (G723_1, g723_1);
     REGISTER_DECODER (GSM, gsm);
     REGISTER_DECODER (GSM_MS, gsm_ms);
     REGISTER_DECODER (IAC, iac);
diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
new file mode 100644
index 0000000..df14a46
--- /dev/null
+++ b/libavcodec/g723_1.c
@@ -0,0 +1,1175 @@
+/*
+ * G.723.1 compatible decoder
+ * Copyright (c) 2006 Benjamin Larsson
+ * Copyright (c) 2010 Mohamed Naufal Basheer
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * G.723.1 compatible decoder
+ */
+
+#define BITSTREAM_READER_LE
+#include "libavutil/audioconvert.h"
+#include "libavutil/lzo.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "acelp_vectors.h"
+#include "celp_filters.h"
+#include "celp_math.h"
+#include "lsp.h"
+#include "g723_1_data.h"
+
+/**
+ * G723.1 frame types
+ */
+enum FrameType {
+    ACTIVE_FRAME,        ///< Active speech
+    SID_FRAME,           ///< Silence Insertion Descriptor frame
+    UNTRANSMITTED_FRAME
+};
+
+enum Rate {
+    RATE_6300,
+    RATE_5300
+};
+
+/**
+ * G723.1 unpacked data subframe
+ */
+typedef struct {
+    int ad_cb_lag;     ///< adaptive codebook lag
+    int ad_cb_gain;
+    int dirac_train;
+    int pulse_sign;
+    int grid_index;
+    int amp_index;
+    int pulse_pos;
+} G723_1_Subframe;
+
+/**
+ * Pitch postfilter parameters
+ */
+typedef struct {
+    int     index;    ///< postfilter backward/forward lag
+    int16_t opt_gain; ///< optimal gain
+    int16_t sc_gain;  ///< scaling gain
+} PPFParam;
+
+typedef struct g723_1_context {
+    AVClass *class;
+    AVFrame frame;
+
+    G723_1_Subframe subframe[4];
+    enum FrameType cur_frame_type;
+    enum FrameType past_frame_type;
+    enum Rate cur_rate;
+    uint8_t lsp_index[LSP_BANDS];
+    int pitch_lag[2];
+    int erased_frames;
+
+    int16_t prev_lsp[LPC_ORDER];
+    int16_t prev_excitation[PITCH_MAX];
+    int16_t excitation[PITCH_MAX + FRAME_LEN];
+    int16_t synth_mem[LPC_ORDER];
+    int16_t fir_mem[LPC_ORDER];
+    int     iir_mem[LPC_ORDER];
+
+    int random_seed;
+    int interp_index;
+    int interp_gain;
+    int sid_gain;
+    int cur_gain;
+    int reflection_coef;
+    int pf_gain;
+    int postfilter;
+
+    int16_t audio[FRAME_LEN + LPC_ORDER];
+} G723_1_Context;
+
+static av_cold int g723_1_decode_init(AVCodecContext *avctx)
+{
+    G723_1_Context *p = avctx->priv_data;
+
+    avctx->channel_layout = AV_CH_LAYOUT_MONO;
+    avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
+    avctx->channels       = 1;
+    avctx->sample_rate    = 8000;
+    p->pf_gain            = 1 << 12;
+
+    avcodec_get_frame_defaults(&p->frame);
+    avctx->coded_frame    = &p->frame;
+
+    memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
+
+    return 0;
+}
+
+/**
+ * Unpack the frame into parameters.
+ *
+ * @param p           the context
+ * @param buf         pointer to the input buffer
+ * @param buf_size    size of the input buffer
+ */
+static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
+                            int buf_size)
+{
+    GetBitContext gb;
+    int ad_cb_len;
+    int temp, info_bits, i;
+
+    init_get_bits(&gb, buf, buf_size * 8);
+
+    /* Extract frame type and rate info */
+    info_bits = get_bits(&gb, 2);
+
+    if (info_bits == 3) {
+        p->cur_frame_type = UNTRANSMITTED_FRAME;
+        return 0;
+    }
+
+    /* Extract 24 bit lsp indices, 8 bit for each band */
+    p->lsp_index[2] = get_bits(&gb, 8);
+    p->lsp_index[1] = get_bits(&gb, 8);
+    p->lsp_index[0] = get_bits(&gb, 8);
+
+    if (info_bits == 2) {
+        p->cur_frame_type = SID_FRAME;
+        p->subframe[0].amp_index = get_bits(&gb, 6);
+        return 0;
+    }
+
+    /* Extract the info common to both rates */
+    p->cur_rate       = info_bits ? RATE_5300 : RATE_6300;
+    p->cur_frame_type = ACTIVE_FRAME;
+
+    p->pitch_lag[0] = get_bits(&gb, 7);
+    if (p->pitch_lag[0] > 123)       /* test if forbidden code */
+        return -1;
+    p->pitch_lag[0] += PITCH_MIN;
+    p->subframe[1].ad_cb_lag = get_bits(&gb, 2);
+
+    p->pitch_lag[1] = get_bits(&gb, 7);
+    if (p->pitch_lag[1] > 123)
+        return -1;
+    p->pitch_lag[1] += PITCH_MIN;
+    p->subframe[3].ad_cb_lag = get_bits(&gb, 2);
+    p->subframe[0].ad_cb_lag = 1;
+    p->subframe[2].ad_cb_lag = 1;
+
+    for (i = 0; i < SUBFRAMES; i++) {
+        /* Extract combined gain */
+        temp = get_bits(&gb, 12);
+        ad_cb_len = 170;
+        p->subframe[i].dirac_train = 0;
+        if (p->cur_rate == RATE_6300 && p->pitch_lag[i >> 1] < SUBFRAME_LEN - 2) {
+            p->subframe[i].dirac_train = temp >> 11;
+            temp &= 0x7FF;
+            ad_cb_len = 85;
+        }
+        p->subframe[i].ad_cb_gain = FASTDIV(temp, GAIN_LEVELS);
+        if (p->subframe[i].ad_cb_gain < ad_cb_len) {
+            p->subframe[i].amp_index = temp - p->subframe[i].ad_cb_gain *
+                                       GAIN_LEVELS;
+        } else {
+            return -1;
+        }
+    }
+
+    p->subframe[0].grid_index = get_bits(&gb, 1);
+    p->subframe[1].grid_index = get_bits(&gb, 1);
+    p->subframe[2].grid_index = get_bits(&gb, 1);
+    p->subframe[3].grid_index = get_bits(&gb, 1);
+
+    if (p->cur_rate == RATE_6300) {
+        skip_bits(&gb, 1);  /* skip reserved bit */
+
+        /* Compute pulse_pos index using the 13-bit combined position index */
+        temp = get_bits(&gb, 13);
+        p->subframe[0].pulse_pos = temp / 810;
+
+        temp -= p->subframe[0].pulse_pos * 810;
+        p->subframe[1].pulse_pos = FASTDIV(temp, 90);
+
+        temp -= p->subframe[1].pulse_pos * 90;
+        p->subframe[2].pulse_pos = FASTDIV(temp, 9);
+        p->subframe[3].pulse_pos = temp - p->subframe[2].pulse_pos * 9;
+
+        p->subframe[0].pulse_pos = (p->subframe[0].pulse_pos << 16) +
+                                   get_bits(&gb, 16);
+        p->subframe[1].pulse_pos = (p->subframe[1].pulse_pos << 14) +
+                                   get_bits(&gb, 14);
+        p->subframe[2].pulse_pos = (p->subframe[2].pulse_pos << 16) +
+                                   get_bits(&gb, 16);
+        p->subframe[3].pulse_pos = (p->subframe[3].pulse_pos << 14) +
+                                   get_bits(&gb, 14);
+
+        p->subframe[0].pulse_sign = get_bits(&gb, 6);
+        p->subframe[1].pulse_sign = get_bits(&gb, 5);
+        p->subframe[2].pulse_sign = get_bits(&gb, 6);
+        p->subframe[3].pulse_sign = get_bits(&gb, 5);
+    } else { /* 5300 bps */
+        p->subframe[0].pulse_pos  = get_bits(&gb, 12);
+        p->subframe[1].pulse_pos  = get_bits(&gb, 12);
+        p->subframe[2].pulse_pos  = get_bits(&gb, 12);
+        p->subframe[3].pulse_pos  = get_bits(&gb, 12);
+
+        p->subframe[0].pulse_sign = get_bits(&gb, 4);
+        p->subframe[1].pulse_sign = get_bits(&gb, 4);
+        p->subframe[2].pulse_sign = get_bits(&gb, 4);
+        p->subframe[3].pulse_sign = get_bits(&gb, 4);
+    }
+
+    return 0;
+}
+
+/**
+ * Bitexact implementation of sqrt(val/2).
+ */
+static int16_t square_root(int val)
+{
+    int16_t res = 0;
+    int16_t exp = 0x4000;
+    int i;
+
+    for (i = 0; i < 14; i ++) {
+        int res_exp = res + exp;
+        if (val >= res_exp * res_exp << 1)
+            res += exp;
+        exp >>= 1;
+    }
+    return res;
+}
+
+/**
+ * Calculate the number of left-shifts required for normalizing the input.
+ *
+ * @param num   input number
+ * @param width width of the input, 16 bits(0) / 32 bits(1)
+ */
+static int normalize_bits(int num, int width)
+{
+    if (!num)
+        return 0;
+    if (num == -1)
+        return width;
+    if (num < 0)
+        num = ~num;
+
+    return width - av_log2(num);
+}
+
+/**
+ * Scale vector contents based on the largest of their absolutes.
+ */
+static int scale_vector(int16_t *vector, int length)
+{
+    int bits, scale, max = 0;
+    int i;
+
+
+    for (i = 0; i < length; i++)
+        max = FFMAX(max, FFABS(vector[i]));
+
+    bits  = normalize_bits(max, 15);
+    scale = (bits == 15) ? 0x7FFF : (1 << bits);
+
+    for (i = 0; i < length; i++)
+        vector[i] = (vector[i] * scale) >> 4;
+
+    return bits - 3;
+}
+
+/**
+ * Perform inverse quantization of LSP frequencies.
+ *
+ * @param cur_lsp    the current LSP vector
+ * @param prev_lsp   the previous LSP vector
+ * @param lsp_index  VQ indices
+ * @param bad_frame  bad frame flag
+ */
+static void inverse_quant(int16_t *cur_lsp, int16_t *prev_lsp,
+                          uint8_t *lsp_index, int bad_frame)
+{
+    int min_dist, pred;
+    int i, j, temp, stable;
+
+    /* Check for frame erasure */
+    if (!bad_frame) {
+        min_dist     = 0x100;
+        pred         = 12288;
+    } else {
+        min_dist     = 0x200;
+        pred         = 23552;
+        lsp_index[0] = lsp_index[1] = lsp_index[2] = 0;
+    }
+
+    /* Get the VQ table entry corresponding to the transmitted index */
+    cur_lsp[0] = lsp_band0[lsp_index[0]][0];
+    cur_lsp[1] = lsp_band0[lsp_index[0]][1];
+    cur_lsp[2] = lsp_band0[lsp_index[0]][2];
+    cur_lsp[3] = lsp_band1[lsp_index[1]][0];
+    cur_lsp[4] = lsp_band1[lsp_index[1]][1];
+    cur_lsp[5] = lsp_band1[lsp_index[1]][2];
+    cur_lsp[6] = lsp_band2[lsp_index[2]][0];
+    cur_lsp[7] = lsp_band2[lsp_index[2]][1];
+    cur_lsp[8] = lsp_band2[lsp_index[2]][2];
+    cur_lsp[9] = lsp_band2[lsp_index[2]][3];
+
+    /* Add predicted vector & DC component to the previously quantized vector */
+    for (i = 0; i < LPC_ORDER; i++) {
+        temp        = ((prev_lsp[i] - dc_lsp[i]) * pred + (1 << 14)) >> 15;
+        cur_lsp[i] += dc_lsp[i] + temp;
+    }
+
+    for (i = 0; i < LPC_ORDER; i++) {
+        cur_lsp[0]             = FFMAX(cur_lsp[0],  0x180);
+        cur_lsp[LPC_ORDER - 1] = FFMIN(cur_lsp[LPC_ORDER - 1], 0x7e00);
+
+        /* Stability check */
+        for (j = 1; j < LPC_ORDER; j++) {
+            temp = min_dist + cur_lsp[j - 1] - cur_lsp[j];
+            if (temp > 0) {
+                temp >>= 1;
+                cur_lsp[j - 1] -= temp;
+                cur_lsp[j]     += temp;
+            }
+        }
+        stable = 1;
+        for (j = 1; j < LPC_ORDER; j++) {
+            temp = cur_lsp[j - 1] + min_dist - cur_lsp[j] - 4;
+            if (temp > 0) {
+                stable = 0;
+                break;
+            }
+        }
+        if (stable)
+            break;
+    }
+    if (!stable)
+        memcpy(cur_lsp, prev_lsp, LPC_ORDER * sizeof(*cur_lsp));
+}
+
+/**
+ * Bitexact implementation of 2ab scaled by 1/2^16.
+ *
+ * @param a 32 bit multiplicand
+ * @param b 16 bit multiplier
+ */
+#define MULL2(a, b) \
+        ((((a) >> 16) * (b) << 1) + (((a) & 0xffff) * (b) >> 15))
+
+/**
+ * Convert LSP frequencies to LPC coefficients.
+ *
+ * @param lpc buffer for LPC coefficients
+ */
+static void lsp2lpc(int16_t *lpc)
+{
+    int f1[LPC_ORDER / 2 + 1];
+    int f2[LPC_ORDER / 2 + 1];
+    int i, j;
+
+    /* Calculate negative cosine */
+    for (j = 0; j < LPC_ORDER; j++) {
+        int index     = lpc[j] >> 7;
+        int offset    = lpc[j] & 0x7f;
+        int64_t temp1 = cos_tab[index] << 16;
+        int temp2     = (cos_tab[index + 1] - cos_tab[index]) *
+                          ((offset << 8) + 0x80) << 1;
+
+        lpc[j] = -(av_clipl_int32(((temp1 + temp2) << 1) + (1 << 15)) >> 16);
+    }
+
+    /*
+     * Compute sum and difference polynomial coefficients
+     * (bitexact alternative to lsp2poly() in lsp.c)
+     */
+    /* Initialize with values in Q28 */
+    f1[0] = 1 << 28;
+    f1[1] = (lpc[0] << 14) + (lpc[2] << 14);
+    f1[2] = lpc[0] * lpc[2] + (2 << 28);
+
+    f2[0] = 1 << 28;
+    f2[1] = (lpc[1] << 14) + (lpc[3] << 14);
+    f2[2] = lpc[1] * lpc[3] + (2 << 28);
+
+    /*
+     * Calculate and scale the coefficients by 1/2 in
+     * each iteration for a final scaling factor of Q25
+     */
+    for (i = 2; i < LPC_ORDER / 2; i++) {
+        f1[i + 1] = f1[i - 1] + MULL2(f1[i], lpc[2 * i]);
+        f2[i + 1] = f2[i - 1] + MULL2(f2[i], lpc[2 * i + 1]);
+
+        for (j = i; j >= 2; j--) {
+            f1[j] = MULL2(f1[j - 1], lpc[2 * i]) +
+                    (f1[j] >> 1) + (f1[j - 2] >> 1);
+            f2[j] = MULL2(f2[j - 1], lpc[2 * i + 1]) +
+                    (f2[j] >> 1) + (f2[j - 2] >> 1);
+        }
+
+        f1[0] >>= 1;
+        f2[0] >>= 1;
+        f1[1] = ((lpc[2 * i]     << 16 >> i) + f1[1]) >> 1;
+        f2[1] = ((lpc[2 * i + 1] << 16 >> i) + f2[1]) >> 1;
+    }
+
+    /* Convert polynomial coefficients to LPC coefficients */
+    for (i = 0; i < LPC_ORDER / 2; i++) {
+        int64_t ff1 = f1[i + 1] + f1[i];
+        int64_t ff2 = f2[i + 1] - f2[i];
+
+        lpc[i] = av_clipl_int32(((ff1 + ff2) << 3) + (1 << 15)) >> 16;
+        lpc[LPC_ORDER - i - 1] = av_clipl_int32(((ff1 - ff2) << 3) +
+                                                (1 << 15)) >> 16;
+    }
+}
+
+/**
+ * Quantize LSP frequencies by interpolation and convert them to
+ * the corresponding LPC coefficients.
+ *
+ * @param lpc      buffer for LPC coefficients
+ * @param cur_lsp  the current LSP vector
+ * @param prev_lsp the previous LSP vector
+ */
+static void lsp_interpolate(int16_t *lpc, int16_t *cur_lsp, int16_t *prev_lsp)
+{
+    int i;
+    int16_t *lpc_ptr = lpc;
+
+    /* cur_lsp * 0.25 + prev_lsp * 0.75 */
+    ff_acelp_weighted_vector_sum(lpc, cur_lsp, prev_lsp,
+                                 4096, 12288, 1 << 13, 14, LPC_ORDER);
+    ff_acelp_weighted_vector_sum(lpc + LPC_ORDER, cur_lsp, prev_lsp,
+                                 8192, 8192, 1 << 13, 14, LPC_ORDER);
+    ff_acelp_weighted_vector_sum(lpc + 2 * LPC_ORDER, cur_lsp, prev_lsp,
+                                 12288, 4096, 1 << 13, 14, LPC_ORDER);
+    memcpy(lpc + 3 * LPC_ORDER, cur_lsp, LPC_ORDER * sizeof(*lpc));
+
+    for (i = 0; i < SUBFRAMES; i++) {
+        lsp2lpc(lpc_ptr);
+        lpc_ptr += LPC_ORDER;
+    }
+}
+
+/**
+ * Generate a train of dirac functions with period as pitch lag.
+ */
+static void gen_dirac_train(int16_t *buf, int pitch_lag)
+{
+    int16_t vector[SUBFRAME_LEN];
+    int i, j;
+
+    memcpy(vector, buf, SUBFRAME_LEN * sizeof(*vector));
+    for (i = pitch_lag; i < SUBFRAME_LEN; i += pitch_lag) {
+        for (j = 0; j < SUBFRAME_LEN - i; j++)
+            buf[i + j] += vector[j];
+    }
+}
+
+/**
+ * Generate fixed codebook excitation vector.
+ *
+ * @param vector    decoded excitation vector
+ * @param subfrm    current subframe
+ * @param cur_rate  current bitrate
+ * @param pitch_lag closed loop pitch lag
+ * @param index     current subframe index
+ */
+static void gen_fcb_excitation(int16_t *vector, G723_1_Subframe subfrm,
+                               enum Rate cur_rate, int pitch_lag, int index)
+{
+    int temp, i, j;
+
+    memset(vector, 0, SUBFRAME_LEN * sizeof(*vector));
+
+    if (cur_rate == RATE_6300) {
+        if (subfrm.pulse_pos >= max_pos[index])
+            return;
+
+        /* Decode amplitudes and positions */
+        j = PULSE_MAX - pulses[index];
+        temp = subfrm.pulse_pos;
+        for (i = 0; i < SUBFRAME_LEN / GRID_SIZE; i++) {
+            temp -= combinatorial_table[j][i];
+            if (temp >= 0)
+                continue;
+            temp += combinatorial_table[j++][i];
+            if (subfrm.pulse_sign & (1 << (PULSE_MAX - j))) {
+                vector[subfrm.grid_index + GRID_SIZE * i] =
+                                        -fixed_cb_gain[subfrm.amp_index];
+            } else {
+                vector[subfrm.grid_index + GRID_SIZE * i] =
+                                         fixed_cb_gain[subfrm.amp_index];
+            }
+            if (j == PULSE_MAX)
+                break;
+        }
+        if (subfrm.dirac_train == 1)
+            gen_dirac_train(vector, pitch_lag);
+    } else { /* 5300 bps */
+        int cb_gain  = fixed_cb_gain[subfrm.amp_index];
+        int cb_shift = subfrm.grid_index;
+        int cb_sign  = subfrm.pulse_sign;
+        int cb_pos   = subfrm.pulse_pos;
+        int offset, beta, lag;
+
+        for (i = 0; i < 8; i += 2) {
+            offset         = ((cb_pos & 7) << 3) + cb_shift + i;
+            vector[offset] = (cb_sign & 1) ? cb_gain : -cb_gain;
+            cb_pos  >>= 3;
+            cb_sign >>= 1;
+        }
+
+        /* Enhance harmonic components */
+        lag  = pitch_contrib[subfrm.ad_cb_gain << 1] + pitch_lag +
+               subfrm.ad_cb_lag - 1;
+        beta = pitch_contrib[(subfrm.ad_cb_gain << 1) + 1];
+
+        if (lag < SUBFRAME_LEN - 2) {
+            for (i = lag; i < SUBFRAME_LEN; i++)
+                vector[i] += beta * vector[i - lag] >> 15;
+        }
+    }
+}
+
+/**
+ * Get delayed contribution from the previous excitation vector.
+ */
+static void get_residual(int16_t *residual, int16_t *prev_excitation, int lag)
+{
+    int offset = PITCH_MAX - PITCH_ORDER / 2 - lag;
+    int i;
+
+    residual[0] = prev_excitation[offset];
+    residual[1] = prev_excitation[offset + 1];
+
+    offset += 2;
+    for (i = 2; i < SUBFRAME_LEN + PITCH_ORDER - 1; i++)
+        residual[i] = prev_excitation[offset + (i - 2) % lag];
+}
+
+static int dot_product(const int16_t *a, const int16_t *b, int length,
+                       int shift)
+{
+    int i, sum = 0;
+
+    for (i = 0; i < length; i++) {
+        int64_t prod = av_clipl_int32(MUL64(a[i], b[i]) << shift);
+        sum = av_clipl_int32(sum + prod);
+    }
+    return sum;
+}
+
+/**
+ * Generate adaptive codebook excitation.
+ */
+static void gen_acb_excitation(int16_t *vector, int16_t *prev_excitation,
+                               int pitch_lag, G723_1_Subframe subfrm,
+                               enum Rate cur_rate)
+{
+    int16_t residual[SUBFRAME_LEN + PITCH_ORDER - 1];
+    const int16_t *cb_ptr;
+    int lag = pitch_lag + subfrm.ad_cb_lag - 1;
+
+    int i;
+    int64_t sum;
+
+    get_residual(residual, prev_excitation, lag);
+
+    /* Select quantization table */
+    if (cur_rate == RATE_6300 && pitch_lag < SUBFRAME_LEN - 2)
+        cb_ptr = adaptive_cb_gain85;
+    else
+        cb_ptr = adaptive_cb_gain170;
+
+    /* Calculate adaptive vector */
+    cb_ptr += subfrm.ad_cb_gain * 20;
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        sum = dot_product(residual + i, cb_ptr, PITCH_ORDER, 1);
+        vector[i] = av_clipl_int32((sum << 1) + (1 << 15)) >> 16;
+    }
+}
+
+/**
+ * Estimate maximum auto-correlation around pitch lag.
+ *
+ * @param p         the context
+ * @param offset    offset of the excitation vector
+ * @param ccr_max   pointer to the maximum auto-correlation
+ * @param pitch_lag decoded pitch lag
+ * @param length    length of autocorrelation
+ * @param dir       forward lag(1) / backward lag(-1)
+ */
+static int autocorr_max(G723_1_Context *p, int offset, int *ccr_max,
+                        int pitch_lag, int length, int dir)
+{
+    int limit, ccr, lag = 0;
+    int16_t *buf = p->excitation + offset;
+    int i;
+
+    pitch_lag = FFMIN(PITCH_MAX - 3, pitch_lag);
+    limit     = FFMIN(FRAME_LEN + PITCH_MAX - offset - length, pitch_lag + 3);
+
+    for (i = pitch_lag - 3; i <= limit; i++) {
+        ccr = dot_product(buf, buf + dir * i, length, 1);
+
+        if (ccr > *ccr_max) {
+            *ccr_max = ccr;
+            lag = i;
+        }
+    }
+    return lag;
+}
+
+/**
+ * Calculate pitch postfilter optimal and scaling gains.
+ *
+ * @param lag      pitch postfilter forward/backward lag
+ * @param ppf      pitch postfilter parameters
+ * @param cur_rate current bitrate
+ * @param tgt_eng  target energy
+ * @param ccr      cross-correlation
+ * @param res_eng  residual energy
+ */
+static void comp_ppf_gains(int lag, PPFParam *ppf, enum Rate cur_rate,
+                           int tgt_eng, int ccr, int res_eng)
+{
+    int pf_residual;     /* square of postfiltered residual */
+    int64_t temp1, temp2;
+
+    ppf->index = lag;
+
+    temp1 = tgt_eng * res_eng >> 1;
+    temp2 = ccr * ccr << 1;
+
+    if (temp2 > temp1) {
+        if (ccr >= res_eng) {
+            ppf->opt_gain = ppf_gain_weight[cur_rate];
+        } else {
+            ppf->opt_gain = (ccr << 15) / res_eng *
+                            ppf_gain_weight[cur_rate] >> 15;
+        }
+        /* pf_res^2 = tgt_eng + 2*ccr*gain + res_eng*gain^2 */
+        temp1       = (tgt_eng << 15) + (ccr * ppf->opt_gain << 1);
+        temp2       = (ppf->opt_gain * ppf->opt_gain >> 15) * res_eng;
+        pf_residual = av_clipl_int32(temp1 + temp2 + (1 << 15)) >> 16;
+
+        if (tgt_eng >= pf_residual << 1) {
+            temp1 = 0x7fff;
+        } else {
+            temp1 = (tgt_eng << 14) / pf_residual;
+        }
+
+        /* scaling_gain = sqrt(tgt_eng/pf_res^2) */
+        ppf->sc_gain = square_root(temp1 << 16);
+    } else {
+        ppf->opt_gain = 0;
+        ppf->sc_gain  = 0x7fff;
+    }
+
+    ppf->opt_gain = av_clip_int16(ppf->opt_gain * ppf->sc_gain >> 15);
+}
+
+/**
+ * Calculate pitch postfilter parameters.
+ *
+ * @param p         the context
+ * @param offset    offset of the excitation vector
+ * @param pitch_lag decoded pitch lag
+ * @param ppf       pitch postfilter parameters
+ * @param cur_rate  current bitrate
+ */
+static void comp_ppf_coeff(G723_1_Context *p, int offset, int pitch_lag,
+                           PPFParam *ppf, enum Rate cur_rate)
+{
+
+    int16_t scale;
+    int i;
+    int64_t temp1, temp2;
+
+    /*
+     * 0 - target energy
+     * 1 - forward cross-correlation
+     * 2 - forward residual energy
+     * 3 - backward cross-correlation
+     * 4 - backward residual energy
+     */
+    int energy[5] = {0, 0, 0, 0, 0};
+    int16_t *buf  = p->excitation + offset;
+    int fwd_lag   = autocorr_max(p, offset, &energy[1], pitch_lag,
+                                 SUBFRAME_LEN, 1);
+    int back_lag  = autocorr_max(p, offset, &energy[3], pitch_lag,
+                                 SUBFRAME_LEN, -1);
+
+    ppf->index    = 0;
+    ppf->opt_gain = 0;
+    ppf->sc_gain  = 0x7fff;
+
+    /* Case 0, Section 3.6 */
+    if (!back_lag && !fwd_lag)
+        return;
+
+    /* Compute target energy */
+    energy[0] = dot_product(buf, buf, SUBFRAME_LEN, 1);
+
+    /* Compute forward residual energy */
+    if (fwd_lag)
+        energy[2] = dot_product(buf + fwd_lag, buf + fwd_lag,
+                                SUBFRAME_LEN, 1);
+
+    /* Compute backward residual energy */
+    if (back_lag)
+        energy[4] = dot_product(buf - back_lag, buf - back_lag,
+                                SUBFRAME_LEN, 1);
+
+    /* Normalize and shorten */
+    temp1 = 0;
+    for (i = 0; i < 5; i++)
+        temp1 = FFMAX(energy[i], temp1);
+
+    scale = normalize_bits(temp1, 31);
+    for (i = 0; i < 5; i++)
+        energy[i] = (energy[i] << scale) >> 16;
+
+    if (fwd_lag && !back_lag) {  /* Case 1 */
+        comp_ppf_gains(fwd_lag,  ppf, cur_rate, energy[0], energy[1],
+                       energy[2]);
+    } else if (!fwd_lag) {       /* Case 2 */
+        comp_ppf_gains(-back_lag, ppf, cur_rate, energy[0], energy[3],
+                       energy[4]);
+    } else {                     /* Case 3 */
+
+        /*
+         * Select the largest of energy[1]^2/energy[2]
+         * and energy[3]^2/energy[4]
+         */
+        temp1 = energy[4] * ((energy[1] * energy[1] + (1 << 14)) >> 15);
+        temp2 = energy[2] * ((energy[3] * energy[3] + (1 << 14)) >> 15);
+        if (temp1 >= temp2) {
+            comp_ppf_gains(fwd_lag, ppf, cur_rate, energy[0], energy[1],
+                           energy[2]);
+        } else {
+            comp_ppf_gains(-back_lag, ppf, cur_rate, energy[0], energy[3],
+                           energy[4]);
+        }
+    }
+}
+
+/**
+ * Classify frames as voiced/unvoiced.
+ *
+ * @param p         the context
+ * @param pitch_lag decoded pitch_lag
+ * @param exc_eng   excitation energy estimation
+ * @param scale     scaling factor of exc_eng
+ *
+ * @return residual interpolation index if voiced, 0 otherwise
+ */
+static int comp_interp_index(G723_1_Context *p, int pitch_lag,
+                             int *exc_eng, int *scale)
+{
+    int offset = PITCH_MAX + 2 * SUBFRAME_LEN;
+    int16_t *buf = p->excitation + offset;
+
+    int index, ccr, tgt_eng, best_eng, temp;
+
+    *scale = scale_vector(p->excitation, FRAME_LEN + PITCH_MAX);
+
+    /* Compute maximum backward cross-correlation */
+    ccr   = 0;
+    index = autocorr_max(p, offset, &ccr, pitch_lag, SUBFRAME_LEN * 2, -1);
+    ccr   = av_clipl_int32((int64_t)ccr + (1 << 15)) >> 16;
+
+    /* Compute target energy */
+    tgt_eng  = dot_product(buf, buf, SUBFRAME_LEN * 2, 1);
+    *exc_eng = av_clipl_int32((int64_t)tgt_eng + (1 << 15)) >> 16;
+
+    if (ccr <= 0)
+        return 0;
+
+    /* Compute best energy */
+    best_eng = dot_product(buf - index, buf - index,
+                           SUBFRAME_LEN * 2, 1);
+    best_eng = av_clipl_int32((int64_t)best_eng + (1 << 15)) >> 16;
+
+    temp = best_eng * *exc_eng >> 3;
+
+    if (temp < ccr * ccr)
+        return index;
+    else
+        return 0;
+}
+
+/**
+ * Peform residual interpolation based on frame classification.
+ *
+ * @param buf   decoded excitation vector
+ * @param out   output vector
+ * @param lag   decoded pitch lag
+ * @param gain  interpolated gain
+ * @param rseed seed for random number generator
+ */
+static void residual_interp(int16_t *buf, int16_t *out, int lag,
+                            int gain, int *rseed)
+{
+    int i;
+    if (lag) { /* Voiced */
+        int16_t *vector_ptr = buf + PITCH_MAX;
+        /* Attenuate */
+        for (i = 0; i < lag; i++)
+            vector_ptr[i - lag] = vector_ptr[i - lag] * 3 >> 2;
+        av_memcpy_backptr((uint8_t*)vector_ptr, lag * sizeof(*vector_ptr),
+                          FRAME_LEN * sizeof(*vector_ptr));
+        memcpy(out, vector_ptr, FRAME_LEN * sizeof(*vector_ptr));
+    } else {  /* Unvoiced */
+        for (i = 0; i < FRAME_LEN; i++) {
+            *rseed = *rseed * 521 + 259;
+            out[i] = gain * *rseed >> 15;
+        }
+        memset(buf, 0, (FRAME_LEN + PITCH_MAX) * sizeof(*buf));
+    }
+}
+
+/**
+ * Perform IIR filtering.
+ *
+ * @param fir_coef FIR coefficients
+ * @param iir_coef IIR coefficients
+ * @param src      source vector
+ * @param dest     destination vector
+ */
+static inline void iir_filter(int16_t *fir_coef, int16_t *iir_coef,
+                              int16_t *src, int *dest)
+{
+    int m, n;
+
+    for (m = 0; m < SUBFRAME_LEN; m++) {
+        int64_t filter = 0;
+        for (n = 1; n <= LPC_ORDER; n++) {
+            filter -= fir_coef[n - 1] * src[m - n] -
+                      iir_coef[n - 1] * (dest[m - n] >> 16);
+        }
+
+        dest[m] = av_clipl_int32((src[m] << 16) + (filter << 3) + (1 << 15));
+    }
+}
+
+/**
+ * Adjust gain of postfiltered signal.
+ *
+ * @param p      the context
+ * @param buf    postfiltered output vector
+ * @param energy input energy coefficient
+ */
+static void gain_scale(G723_1_Context *p, int16_t * buf, int energy)
+{
+    int num, denom, gain, bits1, bits2;
+    int i;
+
+    num   = energy;
+    denom = 0;
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t temp = buf[i] >> 2;
+        temp  = av_clipl_int32(MUL64(temp, temp) << 1);
+        denom = av_clipl_int32(denom + temp);
+    }
+
+    if (num && denom) {
+        bits1   = normalize_bits(num,   31);
+        bits2   = normalize_bits(denom, 31);
+        num     = num << bits1 >> 1;
+        denom <<= bits2;
+
+        bits2 = 5 + bits1 - bits2;
+        bits2 = FFMAX(0, bits2);
+
+        gain = (num >> 1) / (denom >> 16);
+        gain = square_root(gain << 16 >> bits2);
+    } else {
+        gain = 1 << 12;
+    }
+
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        p->pf_gain = ((p->pf_gain << 4) - p->pf_gain + gain + (1 << 3)) >> 4;
+        buf[i]     = av_clip_int16((buf[i] * (p->pf_gain + (p->pf_gain >> 4)) +
+                                   (1 << 10)) >> 11);
+    }
+}
+
+/**
+ * Perform formant filtering.
+ *
+ * @param p   the context
+ * @param lpc quantized lpc coefficients
+ * @param buf output buffer
+ */
+static void formant_postfilter(G723_1_Context *p, int16_t *lpc, int16_t *buf)
+{
+    int16_t filter_coef[2][LPC_ORDER], *buf_ptr;
+    int filter_signal[LPC_ORDER + FRAME_LEN], *signal_ptr;
+    int i, j, k;
+
+    memcpy(buf, p->fir_mem, LPC_ORDER * sizeof(*buf));
+    memcpy(filter_signal, p->iir_mem, LPC_ORDER * sizeof(*filter_signal));
+
+    for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) {
+        for (k = 0; k < LPC_ORDER; k++) {
+            filter_coef[0][k] = (-lpc[k] * postfilter_tbl[0][k] +
+                                 (1 << 14)) >> 15;
+            filter_coef[1][k] = (-lpc[k] * postfilter_tbl[1][k] +
+                                 (1 << 14)) >> 15;
+        }
+        iir_filter(filter_coef[0], filter_coef[1], buf + i,
+                   filter_signal + i);
+    }
+
+    memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(*p->fir_mem));
+    memcpy(p->iir_mem, filter_signal + FRAME_LEN,
+           LPC_ORDER * sizeof(*p->iir_mem));
+
+    buf_ptr    = buf + LPC_ORDER;
+    signal_ptr = filter_signal + LPC_ORDER;
+    for (i = 0; i < SUBFRAMES; i++) {
+        int16_t temp_vector[SUBFRAME_LEN];
+        int16_t temp;
+        int auto_corr[2];
+        int scale, energy;
+
+        /* Normalize */
+        memcpy(temp_vector, buf_ptr, SUBFRAME_LEN * sizeof(*temp_vector));
+        scale = scale_vector(temp_vector, SUBFRAME_LEN);
+
+        /* Compute auto correlation coefficients */
+        auto_corr[0] = dot_product(temp_vector, temp_vector + 1,
+                                   SUBFRAME_LEN - 1, 1);
+        auto_corr[1] = dot_product(temp_vector, temp_vector, SUBFRAME_LEN, 1);
+
+        /* 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;
+        temp = (p->reflection_coef * 0xffffc >> 3) & 0xfffc;
+
+        /* Compensation filter */
+        for (j = 0; j < SUBFRAME_LEN; j++) {
+            buf_ptr[j] = av_clipl_int32(signal_ptr[j] +
+                                        ((signal_ptr[j - 1] >> 16) *
+                                         temp << 1)) >> 16;
+        }
+
+        /* 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;
+
+        gain_scale(p, buf_ptr, energy);
+
+        buf_ptr    += SUBFRAME_LEN;
+        signal_ptr += SUBFRAME_LEN;
+    }
+}
+
+static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
+                               int *got_frame_ptr, AVPacket *avpkt)
+{
+    G723_1_Context *p  = avctx->priv_data;
+    const uint8_t *buf = avpkt->data;
+    int buf_size       = avpkt->size;
+    int dec_mode       = buf[0] & 3;
+
+    PPFParam ppf[SUBFRAMES];
+    int16_t cur_lsp[LPC_ORDER];
+    int16_t lpc[SUBFRAMES * LPC_ORDER];
+    int16_t acb_vector[SUBFRAME_LEN];
+    int16_t *vector_ptr;
+    int bad_frame = 0, i, j, ret;
+
+    if (buf_size < frame_size[dec_mode]) {
+        if (buf_size)
+            av_log(avctx, AV_LOG_WARNING,
+                   "Expected %d bytes, got %d - skipping packet\n",
+                   frame_size[dec_mode], buf_size);
+        *got_frame_ptr = 0;
+        return buf_size;
+    }
+
+    if (unpack_bitstream(p, buf, buf_size) < 0) {
+        bad_frame = 1;
+        if (p->past_frame_type == ACTIVE_FRAME)
+            p->cur_frame_type = ACTIVE_FRAME;
+        else
+            p->cur_frame_type = UNTRANSMITTED_FRAME;
+    }
+
+    p->frame.nb_samples = FRAME_LEN;
+    if ((ret = avctx->get_buffer(avctx, &p->frame)) < 0) {
+         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+         return ret;
+    }
+
+    if (p->cur_frame_type == ACTIVE_FRAME) {
+        if (!bad_frame)
+            p->erased_frames = 0;
+        else if (p->erased_frames != 3)
+            p->erased_frames++;
+
+        inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, bad_frame);
+        lsp_interpolate(lpc, cur_lsp, p->prev_lsp);
+
+        /* Save the lsp_vector for the next frame */
+        memcpy(p->prev_lsp, cur_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
+
+        /* Generate the excitation for the frame */
+        memcpy(p->excitation, p->prev_excitation,
+               PITCH_MAX * sizeof(*p->excitation));
+        vector_ptr = p->excitation + PITCH_MAX;
+        if (!p->erased_frames) {
+            /* Update interpolation gain memory */
+            p->interp_gain = fixed_cb_gain[(p->subframe[2].amp_index +
+                                            p->subframe[3].amp_index) >> 1];
+            for (i = 0; i < SUBFRAMES; i++) {
+                gen_fcb_excitation(vector_ptr, p->subframe[i], p->cur_rate,
+                                   p->pitch_lag[i >> 1], i);
+                gen_acb_excitation(acb_vector, &p->excitation[SUBFRAME_LEN * i],
+                                   p->pitch_lag[i >> 1], p->subframe[i],
+                                   p->cur_rate);
+                /* Get the total excitation */
+                for (j = 0; j < SUBFRAME_LEN; j++) {
+                    vector_ptr[j] = av_clip_int16(vector_ptr[j] << 1);
+                    vector_ptr[j] = av_clip_int16(vector_ptr[j] +
+                                                  acb_vector[j]);
+                }
+                vector_ptr += SUBFRAME_LEN;
+            }
+
+            vector_ptr = p->excitation + PITCH_MAX;
+
+            /* Save the excitation */
+            memcpy(p->audio, vector_ptr, FRAME_LEN * sizeof(*p->audio));
+
+            p->interp_index = comp_interp_index(p, p->pitch_lag[1],
+                                                &p->sid_gain, &p->cur_gain);
+
+            if (p->postfilter) {
+                i = PITCH_MAX;
+                for (j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
+                    comp_ppf_coeff(p, i, p->pitch_lag[j >> 1],
+                                   ppf + j, p->cur_rate);
+            }
+
+            /* Restore the original excitation */
+            memcpy(p->excitation, p->prev_excitation,
+                   PITCH_MAX * sizeof(*p->excitation));
+            memcpy(vector_ptr, p->audio, FRAME_LEN * sizeof(*vector_ptr));
+
+            /* Peform pitch postfiltering */
+            if (p->postfilter)
+                for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
+                    ff_acelp_weighted_vector_sum(p->audio + LPC_ORDER + i,
+                                                 vector_ptr + i,
+                                                 vector_ptr + i + ppf[j].index,
+                                                 ppf[j].sc_gain,
+                                                 ppf[j].opt_gain,
+                                                 1 << 14, 15, SUBFRAME_LEN);
+
+        } else {
+            p->interp_gain = (p->interp_gain * 3 + 2) >> 2;
+            if (p->erased_frames == 3) {
+                /* Mute output */
+                memset(p->excitation, 0,
+                       (FRAME_LEN + PITCH_MAX) * sizeof(*p->excitation));
+                memset(p->frame.data[0], 0,
+                       (FRAME_LEN + LPC_ORDER) * sizeof(int16_t));
+            } else {
+                /* Regenerate frame */
+                residual_interp(p->excitation, p->audio + LPC_ORDER, p->interp_index,
+                                p->interp_gain, &p->random_seed);
+            }
+        }
+        /* Save the excitation for the next frame */
+        memcpy(p->prev_excitation, p->excitation + FRAME_LEN,
+               PITCH_MAX * sizeof(*p->excitation));
+    } else {
+        memset(p->frame.data[0], 0, FRAME_LEN * 2);
+        av_log(avctx, AV_LOG_WARNING,
+               "G.723.1: Comfort noise generation not supported yet\n");
+
+        *got_frame_ptr   = 1;
+        *(AVFrame *)data = p->frame;
+        return frame_size[dec_mode];
+    }
+
+    p->past_frame_type = p->cur_frame_type;
+
+    memcpy(p->audio, p->synth_mem, LPC_ORDER * sizeof(*p->audio));
+    for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
+        ff_celp_lp_synthesis_filter(p->audio + i, &lpc[j * LPC_ORDER],
+                                    p->audio + i, SUBFRAME_LEN, LPC_ORDER,
+                                    0, 1, 1 << 12);
+    memcpy(p->synth_mem, p->audio + FRAME_LEN, LPC_ORDER * sizeof(*p->audio));
+
+    if (p->postfilter)
+        formant_postfilter(p, lpc, p->audio);
+
+    memcpy(p->frame.data[0], p->audio + LPC_ORDER, FRAME_LEN * 2);
+
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = p->frame;
+
+    return frame_size[dec_mode];
+}
+
+#define OFFSET(x) offsetof(G723_1_Context, x)
+#define AD     AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+    { "postfilter", "postfilter on/off", OFFSET(postfilter), AV_OPT_TYPE_INT,
+      { 1 }, 0, 1, AD },
+    { NULL }
+};
+
+
+static const AVClass g723_1dec_class = {
+    .class_name = "G.723.1 decoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_g723_1_decoder = {
+    .name           = "g723_1",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = CODEC_ID_G723_1,
+    .priv_data_size = sizeof(G723_1_Context),
+    .init           = g723_1_decode_init,
+    .decode         = g723_1_decode_frame,
+    .long_name      = NULL_IF_CONFIG_SMALL("G.723.1"),
+    .capabilities   = CODEC_CAP_SUBFRAMES,
+    .priv_class     = &g723_1dec_class,
+};
diff --git a/libavcodec/g723_1_data.h b/libavcodec/g723_1_data.h
new file mode 100644
index 0000000..82446b3
--- /dev/null
+++ b/libavcodec/g723_1_data.h
@@ -0,0 +1,1194 @@
+/*
+ * G.723.1 compatible decoder data tables.
+ * Copyright (c) 2006 Benjamin Larsson
+ * Copyright (c) 2010 Mohamed Naufal Basheer
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * G.723.1 compatible decoder data tables
+ */
+
+#ifndef AVCODEC_G723_1_DATA_H
+#define AVCODEC_G723_1_DATA_H
+
+#include <stdint.h>
+
+#define SUBFRAMES       4
+#define SUBFRAME_LEN    60
+#define FRAME_LEN       (SUBFRAME_LEN << 2)
+#define LPC_ORDER       10
+#define LSP_BANDS       3
+#define LSP_CB_SIZE     256
+#define PITCH_MIN       18
+#define PITCH_MAX       (PITCH_MIN + 127)
+#define PITCH_ORDER     5
+#define GRID_SIZE       2
+#define PULSE_MAX       6
+#define GAIN_LEVELS     24
+#define COS_TBL_SIZE    512
+
+static const uint8_t frame_size[4] = { 24, 20, 4, 1 };
+
+/* Postfilter gain weighting factors scaled by 2^15 */
+static const int16_t ppf_gain_weight[2] = { 0x1800, 0x2000 };
+
+/* LSP DC component */
+static const int16_t dc_lsp[LPC_ORDER] = {
+    0x0c3b, 0x1271, 0x1e0a, 0x2a36, 0x3630,
+    0x406f, 0x4d28, 0x56f4, 0x638c, 0x6c46
+};
+
+/* Cosine table scaled by 2^14 */
+static const int16_t cos_tab[COS_TBL_SIZE] = {
+    16384,  16383,  16379,  16373,  16364,  16353,  16340,  16324,
+    16305,  16284,  16261,  16235,  16207,  16176,  16143,  16107,
+    16069,  16029,  15986,  15941,  15893,  15843,  15791,  15736,
+    15679,  15619,  15557,  15493,  15426,  15357,  15286,  15213,
+    15137,  15059,  14978,  14896,  14811,  14724,  14635,  14543,
+    14449,  14354,  14256,  14155,  14053,  13949,  13842,  13733,
+    13623,  13510,  13395,  13279,  13160,  13039,  12916,  12792,
+    12665,  12537,  12406,  12274,  12140,  12004,  11866,  11727,
+    11585,  11442,  11297,  11151,  11003,  10853,  10702,  10549,
+    10394,  10238,  10080,   9921,   9760,   9598,   9434,   9269,
+     9102,   8935,   8765,   8595,   8423,   8250,   8076,   7900,
+     7723,   7545,   7366,   7186,   7005,   6823,   6639,   6455,
+     6270,   6084,   5897,   5708,   5520,   5330,   5139,   4948,
+     4756,   4563,   4370,   4176,   3981,   3786,   3590,   3393,
+     3196,   2999,   2801,   2603,   2404,   2205,   2006,   1806,
+     1606,   1406,   1205,   1005,    804,    603,    402,    201,
+        0,   -201,   -402,   -603,   -804,  -1005,  -1205,  -1406,
+    -1606,  -1806,  -2006,  -2205,  -2404,  -2603,  -2801,  -2999,
+    -3196,  -3393,  -3590,  -3786,  -3981,  -4176,  -4370,  -4563,
+    -4756,  -4948,  -5139,  -5330,  -5520,  -5708,  -5897,  -6084,
+    -6270,  -6455,  -6639,  -6823,  -7005,  -7186,  -7366,  -7545,
+    -7723,  -7900,  -8076,  -8250,  -8423,  -8595,  -8765,  -8935,
+    -9102,  -9269,  -9434,  -9598,  -9760,  -9921, -10080, -10238,
+   -10394, -10549, -10702, -10853, -11003, -11151, -11297, -11442,
+   -11585, -11727, -11866, -12004, -12140, -12274, -12406, -12537,
+   -12665, -12792, -12916, -13039, -13160, -13279, -13395, -13510,
+   -13623, -13733, -13842, -13949, -14053, -14155, -14256, -14354,
+   -14449, -14543, -14635, -14724, -14811, -14896, -14978, -15059,
+   -15137, -15213, -15286, -15357, -15426, -15493, -15557, -15619,
+   -15679, -15736, -15791, -15843, -15893, -15941, -15986, -16029,
+   -16069, -16107, -16143, -16176, -16207, -16235, -16261, -16284,
+   -16305, -16324, -16340, -16353, -16364, -16373, -16379, -16383,
+   -16384, -16383, -16379, -16373, -16364, -16353, -16340, -16324,
+   -16305, -16284, -16261, -16235, -16207, -16176, -16143, -16107,
+   -16069, -16029, -15986, -15941, -15893, -15843, -15791, -15736,
+   -15679, -15619, -15557, -15493, -15426, -15357, -15286, -15213,
+   -15137, -15059, -14978, -14896, -14811, -14724, -14635, -14543,
+   -14449, -14354, -14256, -14155, -14053, -13949, -13842, -13733,
+   -13623, -13510, -13395, -13279, -13160, -13039, -12916, -12792,
+   -12665, -12537, -12406, -12274, -12140, -12004, -11866, -11727,
+   -11585, -11442, -11297, -11151, -11003, -10853, -10702, -10549,
+   -10394, -10238, -10080,  -9921,  -9760,  -9598,  -9434,  -9269,
+    -9102,  -8935,  -8765,  -8595,  -8423,  -8250,  -8076,  -7900,
+    -7723,  -7545,  -7366,  -7186,  -7005,  -6823,  -6639,  -6455,
+    -6270,  -6084,  -5897,  -5708,  -5520,  -5330,  -5139,  -4948,
+    -4756,  -4563,  -4370,  -4176,  -3981,  -3786,  -3590,  -3393,
+    -3196,  -2999,  -2801,  -2603,  -2404,  -2205,  -2006,  -1806,
+    -1606,  -1406,  -1205,  -1005,   -804,   -603,   -402,   -201,
+        0,    201,    402,    603,    804,   1005,   1205,   1406,
+     1606,   1806,   2006,   2205,   2404,   2603,   2801,   2999,
+     3196,   3393,   3590,   3786,   3981,   4176,   4370,   4563,
+     4756,   4948,   5139,   5330,   5520,   5708,   5897,   6084,
+     6270,   6455,   6639,   6823,   7005,   7186,   7366,   7545,
+     7723,   7900,   8076,   8250,   8423,   8595,   8765,   8935,
+     9102,   9269,   9434,   9598,   9760,   9921,  10080,  10238,
+    10394,  10549,  10702,  10853,  11003,  11151,  11297,  11442,
+    11585,  11727,  11866,  12004,  12140,  12274,  12406,  12537,
+    12665,  12792,  12916,  13039,  13160,  13279,  13395,  13510,
+    13623,  13733,  13842,  13949,  14053,  14155,  14256,  14354,
+    14449,  14543,  14635,  14724,  14811,  14896,  14978,  15059,
+    15137,  15213,  15286,  15357,  15426,  15493,  15557,  15619,
+    15679,  15736,  15791,  15843,  15893,  15941,  15986,  16029,
+    16069,  16107,  16143,  16176,  16207,  16235,  16261,  16284,
+    16305,  16324,  16340,  16353,  16364,  16373,  16379,  16383,
+};
+
+/* LSP VQ tables */
+static const int16_t lsp_band0[LSP_CB_SIZE][3] = {
+    {    0,      0,      0}, { -270,  -1372,  -1032}, { -541,  -1650,  -1382},
+    { -723,  -2011,  -2213}, { -941,  -1122,  -1942}, { -780,  -1145,  -2454},
+    { -884,  -1309,  -1373}, {-1051,  -1523,  -1766}, {-1083,  -1622,  -2300},
+    { -777,  -1377,  -2147}, { -935,  -1467,  -2763}, { -802,  -1327,  -3471},
+    { -935,  -1959,  -3999}, { -240,    -89,    222}, { -661,   -257,   -160},
+    { -994,   -466,   -419}, { -188,   -164,   -278}, { -342,   -512,   -415},
+    { -607,   -511,   -797}, {   16,     19,   -716}, {  374,    425,   -972},
+    { -346,    245,   -282}, { -265,    506,   -754}, { -620,   -147,   1955},
+    { -742,   -860,   2597}, { -150,   -352,   2704}, {  305,    880,   1954},
+    {  123,    731,   2766}, { -348,    765,   3327}, {  618,    221,   3258},
+    { -178,    -47,   4219}, {  393,   1304,   3842}, {  698,   1702,   4801},
+    {   63,   -584,   1229}, { -215,   -732,   1704}, {  172,   -335,   1909},
+    {   -2,    216,   1797}, {  353,    127,   2205}, {-1208,    188,     11},
+    { -513,    -75,   -683}, { -973,    222,   -646}, { -616,   -843,   -388},
+    { -950,  -1113,   -359}, {-1431,   -623,   -705}, {-1398,  -1063,   -178},
+    {  -45,   -461,     35}, {   -9,   -657,   -216}, {  127,  -1078,     95},
+    { -950,  -1156,    584}, {-1480,  -1494,    449}, { -120,   -705,    516},
+    { -368,   -961,    727}, { -378,   -526,    973}, { -793,   -614,    676},
+    { -801,   -755,   1287}, {-1476,   -340,   1636}, { -505,  -1254,   1543},
+    {-1243,  -1622,   1532}, { -776,  -1477,   -655}, {-1151,  -1296,   -823},
+    {-1153,  -1672,  -1124}, {-1291,  -2003,  -1702}, { -622,  -1283,     57},
+    { -471,  -1611,    509}, {-1060,  -1570,   -139}, { -873,  -2156,   -536},
+    {-1716,  -2021,   -364}, {-2150,  -3218,  -1291}, {-1248,  -1945,  -2904},
+    {-1215,  -2633,  -2855}, {  167,   -244,     84}, {  349,   -412,   -217},
+    {  -40,   -352,    632}, {  227,   -529,    405}, {   68,   -383,   -443},
+    {  167,   -558,   -706}, { -275,   -854,    -14}, { -351,  -1089,   -449},
+    {  341,    -72,   -289}, {  603,   -106,   -474}, {  322,   -219,   -649},
+    {  179,   -317,   -998}, {  450,   -291,   -996}, {  555,    195,   -525},
+    {  784,    272,   -831}, { -148,   -384,   -849}, {   82,   -536,  -1357},
+    {  238,   -172,  -1354}, {  422,   -268,  -1841}, {  297,   -737,  -2079},
+    { -111,   -801,   -598}, {    1,   -668,   -984}, { -131,   -818,  -1299},
+    { -329,   -521,  -1310}, { -151,   -778,  -1834}, {  -93,   -352,  -1746},
+    { -568,   -640,  -1821}, { -509,   -941,  -2183}, {  464,   -815,  -1250},
+    {   79,  -1133,  -1597}, { -184,  -1353,  -2123}, { -196,   -410,  -2427},
+    { -192,   -833,  -2810}, { -259,  -1382,  -3045}, { -217,      4,  -1166},
+    { -800,   -325,  -1219}, { -363,   -830,   -898}, { -661,  -1134,   -960},
+    { -386,   -980,  -1501}, { -627,  -1159,  -1722}, { -903,   -829,   -855},
+    { -685,   -829,  -1313}, {-1065,   -959,  -1405}, {  441,     25,   -847},
+    {  655,    -27,  -1181}, { 1159,   -110,   -705}, {  856,    253,  -1671},
+    {  415,    404,     -1}, {  322,    903,   -398}, {  670,    499,   -292},
+    {  803,    591,   -610}, { 1144,    591,   -814}, {  717,    183,    393},
+    {  857,    381,    106}, {  609,     62,    -27}, {  792,    198,   -325},
+    {  735,    805,     88}, { 1142,    812,     78}, { 1028,    366,   -292},
+    { 1309,    743,   -237}, { 1615,    589,    -79}, { 1010,    639,   -243},
+    {  999,    964,   -311}, { 1500,   1137,   -615}, {  988,    357,    646},
+    { 1227,    667,    683}, { 1164,   1565,    894}, { 1392,   2015,    477},
+    { 1138,    533,    250}, { 1437,    896,    391}, { 1765,   1118,     99},
+    { 1112,   1090,    802}, { 1596,    846,   1134}, {  937,   1161,    279},
+    { 1719,   1254,    683}, { 1338,   1086,     35}, { 1419,   1324,    428},
+    { 1428,   1524,     40}, { 2108,   1594,     89}, { 1015,    544,   1222},
+    { 1121,    925,   1263}, { 1030,   1318,   1485}, { 1295,    789,   1817},
+    { 1323,   1272,   1909}, { 1724,   1237,   1803}, { 1797,   1689,    858},
+    { 2149,   1367,   1301}, { 2302,   1867,    761}, { 2863,   2351,   1053},
+    {   52,    163,    -76}, {  230,    309,   -492}, {  -71,    619,     39},
+    { -218,    856,    499}, { -654,    736,   -207}, { -535,   1259,    155},
+    { -480,   1476,    643}, {  262,   1081,    102}, {  309,   1592,   -182},
+    {  627,   1629,    534}, {  337,    643,    456}, {  758,    670,    713},
+    {  202,   1126,    658}, {  612,   1131,    666}, {  686,   1223,   1136},
+    { -131,    377,    525}, {   42,    708,    907}, {   87,   1488,   1035},
+    {  432,   2117,    904}, {  137,    981,   1332}, { -447,   1014,   1136},
+    { -839,   1793,   1246}, { -559,    297,    198}, { -850,    685,    446},
+    {-1273,    632,    826}, { -401,   -544,    173}, { -753,   -793,    144},
+    { -436,     -9,    772}, { -115,   -243,   1310}, { -670,   -269,    374},
+    {-1027,    -13,    639}, { -887,    -81,   1137}, {-1277,   -455,    158},
+    {-1411,   -720,    736}, {  172,     88,    403}, {  386,    255,    756},
+    { -500,    522,    910}, { -958,    659,   1388}, { -395,    301,   1344},
+    { -356,    768,   1813}, { -613,    841,   2419}, {  445,   -122,    252},
+    {  629,    -87,    723}, {  283,   -253,    870}, {  456,   -116,   1381},
+    {  757,    180,   1059}, {  532,    408,   1509}, {  947,    288,   1806},
+    { 1325,    994,   2524}, {  892,   1219,   3023}, { 1397,   1596,   3406},
+    { 1143,   1552,   2546}, { 1850,   1433,   2710}, {  -10,    134,   1002},
+    {  154,    499,   1323}, {  508,    792,   1117}, {  509,   1340,   1616},
+    {  762,    862,   1608}, {  787,    740,   2320}, {  794,   1727,   1283},
+    {  465,   2108,   1660}, { -120,   1451,   1613}, { -386,   2016,   2169},
+    {  891,   1225,   2050}, {  456,   1480,   2185}, { 1493,   1283,   1209},
+    { 1397,   1636,   1518}, { 1776,   1738,   1552}, { 1572,   1698,   2141},
+    { 1389,   2126,   1271}, { 1959,   2413,   1119}, { 1365,   2892,   1505},
+    { 2206,   1971,   1623}, { 2076,   1950,   2280}, { 1717,   2291,   1867},
+    { 2366,   2515,   1953}, { 2865,   2838,   2522}, { 2535,   3465,   2011},
+    { 3381,   4127,   2638}, {  836,   2667,   2289}, { 1761,   2773,   2337},
+    { 1415,   3325,   2911}, { 2354,   3138,   3126}, { 2659,   4192,   4010},
+    { 1048,   1786,   1818}, { 1242,   2111,   2240}, { 1512,   2079,   2780},
+    { 1573,   2491,   3138}, { 2230,   2377,   2782}, {  416,   1773,   2704},
+    {  725,   2336,   3297}, { 1252,   2373,   3978}, { 2094,   2268,   3568},
+    { 2011,   2712,   4528}, { 1341,   3507,   3876}, { 1216,   3919,   4922},
+    { 1693,   4793,   6012}
+};
+
+static const int16_t lsp_band1[LSP_CB_SIZE][3] = {
+    {    0,      0,      0}, {-2114,  -1302,     76}, {-2652,  -1278,  -1368},
+    {-2847,   -828,   -349}, {-3812,  -2190,   -349}, {-3946,   -364,   -449},
+    {-2725,  -4492,  -3607}, {-3495,  -4764,  -1744}, {  -51,   -756,     84},
+    { -153,  -1191,    504}, {  108,  -1418,   1167}, { -835,   -896,    390},
+    { -569,  -1702,     87}, {-1151,  -1818,    933}, {-1826,  -2547,    411},
+    {-1842,  -1818,   1451}, {-2438,  -1611,    781}, {-2747,  -2477,   1311},
+    { -940,   1252,    477}, {-1629,   1688,    602}, {-1202,    617,    280},
+    {-1737,    393,    580}, {-1528,   1077,   1199}, {-2165,   -161,   1408},
+    {-2504,  -1087,   2371}, {-3458,   -175,   1395}, {-1397,    -98,   -843},
+    {-2252,   -177,  -1149}, {-1489,   -726,  -1283}, {-1558,   -265,  -1744},
+    {-1867,   -821,  -1897}, {-2062,  -1516,  -2340}, {-2595,  -1142,  -2861},
+    {  170,     46,   -819}, { -193,   -204,  -1151}, {  326,   -196,  -1532},
+    {  780,    329,   -816}, {  201,    369,  -1243}, {  650,   -209,  -1060},
+    { 1144,    -15,  -1216}, { 1203,   -259,  -1867}, { -890,   -564,  -1430},
+    { -638,   -852,  -1921}, {  177,   -739,  -1358}, { -261,   -526,  -1666},
+    {  206,   -407,  -2255}, {  338,   -526,   -822}, {  421,  -1095,  -1009},
+    {  765,   -607,  -1408}, {  825,  -1295,  -2004}, {  357,   -905,  -1815},
+    {  -58,  -1248,  -1588}, { -596,  -1436,  -2046}, {  -73,  -1159,  -2116},
+    { -115,  -1382,  -2581}, { -160,  -1723,  -1952}, {   -6,  -2196,  -2954},
+    { -649,  -1705,  -2603}, { -617,  -1453,  -3282}, { -949,  -2019,  -3102},
+    { -812,   1544,   1937}, {-1854,    574,   2000}, {-1463,   1140,   2649},
+    {-2683,   1748,   1452}, {-2486,   2241,   2523}, {  783,   1910,   1435},
+    {  581,   2682,   1376}, {  236,   2197,   1885}, { -453,   2943,   2057},
+    { -682,   2178,   2565}, {-1342,   3201,   3328}, { -288,   -184,    262},
+    {  121,   -149,   -183}, {  758,   -412,    206}, { 1038,   -204,    853},
+    { 1577,   -457,    700}, {  937,   -640,   -567}, { 1508,   -528,  -1024},
+    { -225,   -527,   -427}, { -564,  -1095,   -332}, { -742,   -353,   -186},
+    {-1288,   -459,     84}, {-1853,   -484,   -274}, {-1554,   -731,    825},
+    {-2425,   -234,    382}, {-1722,    293,   -271}, {-2515,    425,   -564},
+    {-2599,    818,    464}, { -358,    118,   -375}, { -613,    198,   -874},
+    { -690,    683,   -324}, {-1352,   1155,   -168}, {-1093,    129,   -324},
+    {-1184,    611,   -858}, {  433,    386,   -372}, { -120,    486,   -634},
+    {  234,    851,   -631}, {  602,    128,     46}, { 1099,    410,    159},
+    {  715,   -145,   -424}, { 1198,    -85,   -593}, { 1390,    367,   -358},
+    { 1683,    362,   -964}, { 1711,    622,     45}, { 2033,    833,   -383},
+    { 2890,    549,   -506}, {    7,    401,     52}, {   72,    811,    415},
+    {  566,    668,     41}, {  467,   1218,    130}, {   68,    957,   -187},
+    {  -25,   1649,   -103}, { -661,    260,    214}, { -925,    -94,    612},
+    { -321,   -422,    965}, { -788,   -672,   1783}, {  400,   -673,    779},
+    {  741,   -595,   1635}, { -161,    307,    657}, { -382,    836,    871},
+    { -814,    400,   1223}, {  364,    606,   1247}, {   57,     75,   1571},
+    {  151,    471,   2287}, {  -81,   1021,   1502}, {  227,   1470,   1097},
+    {  658,   1275,   1653}, {  664,   1478,   2377}, {  263,   -127,    444},
+    {  264,     89,    969}, {  794,    171,    576}, {  821,    186,   1226},
+    {  404,    462,    517}, {  339,    918,    794}, { 1280,   1423,    196},
+    { 1453,   2019,    365}, { 1615,   1481,    672}, { 2394,   1708,    508},
+    {  806,   1238,    573}, {  713,   1158,   1078}, { 1285,   1436,   1232},
+    { 1790,   1188,   1141}, {  765,    643,    864}, { 1032,    797,   1279},
+    {  900,    563,   1827}, { 1514,    673,   2312}, { 1544,   1129,   3240},
+    { 1469,   1050,   1594}, { 1945,   1318,   1988}, { 2397,   2026,   2060},
+    { 3538,   2057,   2620}, { 1249,   -118,     74}, { 1727,    194,    421},
+    { 2078,    -50,   -463}, {  970,    688,   -432}, { 1149,    952,   -110},
+    { 1254,   1275,   -651}, { 1386,    929,    401}, { 1960,   1167,    232},
+    {  407,   -752,   -243}, {  859,  -1118,    172}, { -227,   -860,   -992},
+    { -796,  -1175,  -1380}, {    8,  -1282,   -388}, {  353,  -1781,  -1037},
+    { -732,   -397,   -807}, { -853,    -28,  -1342}, {-1229,  -1207,  -1959},
+    {-1015,  -1125,  -2543}, {-1452,  -1791,  -2725}, {-1891,  -2416,  -3269},
+    { -918,  -1629,   -783}, { -580,  -2155,   -698}, {-1097,  -2364,    -96},
+    {-1387,  -1513,      7}, {-1588,  -2076,   -664}, {-1473,  -2740,   -784},
+    {-2378,  -3149,    -56}, {-2856,  -2092,   -169}, {-3391,  -3708,    316},
+    {-1176,   -890,   -614}, {-1944,  -1061,   -800}, { -299,  -1517,  -1000},
+    { -640,  -1850,  -1526}, {-1454,  -1536,  -1233}, {-1890,  -1955,  -1756},
+    {-1086,  -1921,  -2122}, { -750,  -2325,  -2260}, {-1325,  -2413,  -2673},
+    {-1114,  -2542,  -3459}, {-1341,  -2901,  -3963}, {-1160,  -2226,  -1393},
+    {-1001,  -2772,  -1573}, {-1594,  -2641,  -1978}, {-1534,  -3046,  -2624},
+    {-2224,  -2196,   -675}, {-2807,  -3054,  -1102}, {-2008,  -2840,  -1186},
+    {-1980,  -3332,  -1695}, {-1715,  -3562,   -505}, {-2527,  -4000,  -1887},
+    {-2333,  -2734,  -2296}, {-3440,  -2401,  -3211}, {-2008,  -3528,  -3337},
+    {-2247,  -3291,  -4510}, { -475,    949,    155}, { -149,   1365,    545},
+    { -757,   1644,   1083}, { -217,   2053,   1353}, {-1433,   2301,   1462},
+    {  495,   1661,    529}, {   10,   2037,    740}, { 2082,   1898,    978},
+    { 2831,   2294,    911}, {  842,    793,    420}, { 1223,   1023,    863},
+    { 1237,    451,    780}, { 1744,    708,    822}, { 1533,    284,   1384},
+    { 2135,    609,   1538}, { 2305,    626,    540}, { 2368,   1187,    955},
+    { 2586,   1255,     -7}, { 3116,   1131,    726}, { 3431,   1730,    428},
+    { 2734,   1648,   1307}, { 2988,   1231,   2010}, { 3523,   2024,   1488},
+    { 1034,   1657,    871}, { 1206,   2163,   1036}, { 1807,   2372,   1233},
+    { 1808,   1769,   1493}, { 1573,   2332,   1779}, { 1216,   1609,   1866},
+    { 1480,   1898,   2513}, {  465,   2708,   2776}, {  771,   3638,   3338},
+    { 1869,   2599,   2623}, { 2825,   2745,   2468}, { 2638,   2439,   1585},
+    { 2094,   2970,   1308}, { 2022,   3057,   1999}, { 3428,   2912,   1816},
+    { 4536,   2974,   2129}, { 1046,   2563,   2086}, { 1363,   3562,   2318},
+    { 2511,   1891,   2984}, { 1866,   2306,   3986}, { 3272,   2924,   3682},
+    { 3146,   3564,   2272}, { 3592,   3968,   2822}, { 2431,   3369,   3069},
+    { 1931,   4709,   3090}, { 2629,   4220,   3986}, { 4639,   4056,   3664},
+    { 4035,   5334,   4912}
+};
+
+static const int16_t lsp_band2[LSP_CB_SIZE][4] = {
+    {    0,      0,      0,      0}, {  601,    512,   -542,    334},
+    {  428,   1087,   -484,   -132}, {  652,    622,   -391,   -572},
+    {  378,    799,    141,   -860}, { 1040,    409,    112,   -554},
+    { 1123,    670,    -75,   -847}, { 1421,    494,   -315,  -1095},
+    {  787,   1001,    114,   -460}, {  988,   1672,    216,   -681},
+    { 1007,   1241,   -132,  -1247}, { 1073,    399,    186,     -5},
+    { 1262,    193,   -694,   -129}, {  325,    196,     51,   -641},
+    {  861,    -59,    350,   -458}, { 1261,    567,    586,   -346},
+    { 1532,    885,    210,   -517}, { 2027,    937,    113,   -792},
+    { 1383,   1064,    334,     38}, { 1964,   1468,    459,    133},
+    { 2062,   1186,    -98,   -121}, { 2577,   1445,    506,   -373},
+    { 2310,   1682,     -2,   -960}, { 2876,   1939,    765,    138},
+    { 3581,   2360,    649,   -414}, {  219,    176,   -398,   -309},
+    {  434,    -78,   -435,   -880}, { -344,    301,    265,   -552},
+    { -915,    470,    657,   -380}, {  419,   -432,   -163,   -453},
+    {  351,   -953,      8,   -562}, {  789,    -43,     20,   -958},
+    {  302,   -594,   -352,  -1159}, { 1040,    108,   -668,   -924},
+    { 1333,    210,  -1217,  -1663}, {  483,    589,   -350,  -1140},
+    { 1003,    824,   -802,  -1184}, {  745,     58,   -589,  -1443},
+    {  346,    247,   -915,  -1683}, {  270,    796,   -720,  -2043},
+    { 1208,    722,   -222,   -193}, { 1486,   1180,   -412,   -672},
+    { 1722,    179,    -69,   -521}, { 2047,    860,   -666,  -1410},
+    { -146,    222,   -281,   -805}, { -189,     90,   -114,  -1307},
+    { -152,   1086,   -241,   -764}, { -439,    733,   -601,  -1302},
+    { -833,   -167,   -351,   -601}, { -856,   -422,   -411,  -1059},
+    { -747,   -355,   -582,  -1644}, { -837,    210,   -916,  -1144},
+    {-1800,     32,   -878,  -1687}, {  -48,    -23,  -1146,     52},
+    { -350,   -409,  -1656,   -364}, {  265,   -728,   -858,   -577},
+    {  458,   -247,  -1141,   -997}, {  691,   -407,  -1988,  -1161},
+    {  -66,   -104,   -705,  -1249}, { -431,    -93,  -1191,  -1844},
+    {  203,   -732,  -1000,  -1693}, {   10,   -832,  -1846,  -1819},
+    {  493,   -128,  -1436,  -1768}, {  488,   -311,  -1730,  -2540},
+    { -653,   -532,  -1150,  -1172}, {-1086,   -289,  -1706,  -1533},
+    { -699,  -1205,  -1216,  -1766}, {-1032,  -1481,  -2074,  -1523},
+    { -721,  -1220,  -2277,  -2600}, {   12,   -539,  -1484,  -1131},
+    {  -40,   -911,  -2106,   -441}, { -471,   -484,  -2267,  -1549},
+    { -141,   -988,  -3006,  -1721}, {-1545,  -2102,   -583,    342},
+    {-1383,  -2772,   -386,    -13}, {-2118,  -2589,  -1205,     72},
+    {-2147,  -3231,   -965,    390}, {-2949,  -3300,   -621,    637},
+    {-3907,  -4138,   -865,    803}, {-1287,   -845,   -375,   -548},
+    {-1416,  -1169,   -487,  -1277}, {-1400,  -1690,  -1027,   -418},
+    {-2018,  -1909,  -1188,  -1260}, {-1418,  -2222,  -2029,   -128},
+    {-2067,  -2998,  -2693,   -310}, { -950,  -1028,  -1538,    185},
+    {-1616,   -915,  -2205,   -549}, {   19,   -821,  -1145,    352},
+    {  184,  -1175,  -1356,   -627}, { -547,  -1088,  -1661,   -911},
+    { -216,  -1502,  -2197,   -948}, { -795,  -1306,  -2374,   -451},
+    { -924,  -1889,  -2796,   -680}, { -600,  -1614,  -3609,   -885},
+    {-2392,  -2528,    319,    303}, {-2908,  -2095,   -310,    573},
+    {-3460,  -2141,     49,   -113}, {-2231,   -448,    675,   -146},
+    {-2805,   -532,   1231,    479}, {-2684,   -486,   -200,    611},
+    {-3525,   -971,   -198,    704}, {-3707,    173,    349,    254},
+    {-4734,  -1447,    -34,    880}, {  777,   -512,    114,    -10},
+    { 1250,    -66,    442,     -5}, {  604,    613,    452,   -352},
+    { 1224,    777,    675,  -1014}, {-1372,    -79,  -1208,   -238},
+    {-2389,    -17,  -1157,   -818}, {-1504,   -673,  -1133,  -1060},
+    {-1984,   -799,  -2005,  -1973}, {-2037,   -798,  -1068,   -105},
+    {-3190,   -899,  -1817,   -194}, { -156,   -886,    394,   -318},
+    { -258,  -1283,    551,    202}, { -536,  -1729,    910,    331},
+    { -847,  -1109,    795,   -163}, {-1171,  -1128,    715,    519},
+    {-1080,  -1319,   1685,    668}, {-1000,  -1921,     96,    211},
+    {-1487,  -2148,    831,    174}, {-1139,   -374,    414,     -4},
+    {-1517,  -1383,    396,   -352}, {-1012,    439,    -59,   -967},
+    {-1812,    706,   -440,  -1030}, {-1971,   -329,    -34,   -827},
+    {-2472,  -1588,   -151,   -606}, {-2161,    374,   -281,     76},
+    {-3012,    231,    -15,   -690}, { 1104,    566,    721,    209},
+    { 1685,    564,    383,     98}, { 1898,    750,    792,    -97},
+    {  556,    -64,    561,    -93}, {  876,    162,    913,    -22},
+    {  961,    675,   1296,    140}, {  756,   -396,    851,    544},
+    {  360,   -303,   1341,    396}, {  878,    -22,   1464,    863},
+    { -309,   -273,    642,   -129}, { -686,    -82,    842,    454},
+    {   -5,    -47,   1069,    998}, {  -94,    967,   1277,    298},
+    { -489,    385,   1473,    746}, { -369,   -717,   1333,    242},
+    {  281,   -993,   1726,    924}, {  464,    601,   1575,   1376},
+    { -250,    206,   2339,   1175}, { -438,    377,   -597,   -285},
+    {-1020,    787,   -790,   -287}, { -458,   -410,    215,    295},
+    { -589,   -860,   -121,    797}, {-1175,    122,   -437,    466},
+    {-1480,   -121,    367,    924}, {  234,    323,    770,   -555},
+    {  145,     30,    996,     26}, {   66,    849,     93,   -145},
+    { -117,   1261,    474,   -399}, {-1495,   1051,    218,   -506},
+    {-1390,    694,    994,     88}, {  616,      7,     78,    304},
+    { 1060,     52,    -62,    835}, {  833,    454,    649,   1359},
+    { -770,    464,     47,     93}, { -574,   1199,    -39,    379},
+    {  114,    -98,    488,    485}, {  727,    244,    606,    696},
+    {  -76,    455,    671,    546}, { -565,    -13,    145,    819},
+    { -376,    569,    448,   1128}, {  218,    122,    265,   1167},
+    {  230,    738,    932,   1003}, {  138,    477,     36,    450},
+    {  404,    787,    -73,   1000}, {  497,   1259,    387,   1231},
+    {   17,    207,    195,    -79}, {  562,    358,     53,   -158},
+    {  493,    387,    478,    189}, {  678,    831,    640,    558},
+    { -197,    523,    613,     57}, {  429,    894,    769,    111},
+    {   67,   1174,    568,    511}, { 1242,    824,    251,    840},
+    { 1419,   1074,    864,    481}, {  924,   1474,    669,    724},
+    { 1539,   1879,    654,   1590}, {  445,    337,   1111,    541},
+    {  472,   1421,   1264,   1094}, {  794,    735,   1103,    668},
+    { 1055,    863,   1192,   1020}, {  778,   1105,    806,   1798},
+    { 1052,   1527,   1587,   2151}, {  881,   1552,   1265,    391},
+    {  726,    872,   1812,    601}, { 1469,    280,   1008,    616},
+    { 1403,    577,   1803,   1244}, { 1650,   1314,   1148,   1072},
+    { 1297,   1669,   1911,   1026}, { 2093,   1044,   2115,   1189},
+    { 1644,   1961,   2587,   1512}, {   25,   -315,     -9,   -106},
+    {  290,   -339,    428,   -444}, {  -68,   -783,    735,    772},
+    {  245,   -555,    468,     47}, {  334,   -895,    814,    146},
+    {  235,    368,   -964,   -959}, { -203,    315,  -1566,  -1217},
+    {  801,     17,   -276,   -354}, {  894,   -495,   -789,   -635},
+    {  716,    291,  -1189,   -357}, {  560,   -260,   -733,     -2},
+    {  679,   -508,  -1429,    211}, {  -51,    -62,   -428,    557},
+    {  322,   -638,   -211,    614}, { -878,  -1057,    -84,    -71},
+    { -388,  -1415,   -167,   -318}, { -754,  -1574,    214,   -539},
+    {-1419,  -2004,    -92,   -787}, {  -47,   -856,   -347,   -255},
+    {   23,  -1211,   -173,    320}, { -658,   -487,   -893,    353},
+    { -783,  -1587,   -584,    507}, {-1420,   -859,   -378,    441},
+    {-2095,  -1491,   -137,    439}, { -321,  -1450,  -1288,    -12},
+    { -359,  -2113,   -553,     -8}, { -831,  -1918,  -1561,     32},
+    {-1014,  -2487,  -1359,   -939}, { -475,   -311,   -169,   -236},
+    { -907,   -426,    276,   -611}, {  -96,   -400,     50,   -710},
+    { -426,  -1022,    -10,   -985}, { -197,   -258,   -744,   -575},
+    { -611,   -930,   -771,   -394}, { -267,   -776,   -612,   -939},
+    { -256,  -1346,   -802,  -1122}, { -796,  -1570,   -825,   -754},
+    {  712,    876,    141,    227}, {  981,   1509,     85,    124},
+    { 1462,   1228,    979,    -39}, { 1734,    999,   1481,    440},
+    { 2293,   1116,    769,    440}, { 2504,   1480,   1241,    356},
+    { 2474,   1909,   1558,    810}, {  917,   1134,    607,   -134},
+    {  509,   1809,    781,   -123}, { 1712,   1506,    559,   -423},
+    { 2037,   2317,    726,   -155}, { 3031,   2676,   1203,    331},
+    { 3664,   3274,   1768,    531}, { 1610,   1839,    867,    183},
+    { 1774,   1972,   1538,     97}, { 1822,   2158,   1282,    659},
+    { 2222,   2758,   1818,    900}, { 3251,   2124,   1723,    996},
+    { 3633,   2336,   2408,   1453}, { 2923,   3517,   2567,   1318},
+};
+
+/*
+ * Used for the coding/decoding of the pulses positions
+ * for the MP-MLQ codebook
+ */
+static const int32_t combinatorial_table[PULSE_MAX][SUBFRAME_LEN/GRID_SIZE] = {
+    {118755, 98280, 80730, 65780L, 53130,
+      42504, 33649, 26334,  20349, 15504,
+      11628,  8568,  6188,   4368,  3003,
+       2002,  1287,   792,    462,   252,
+        126,    56,    21,      6,     1,
+          0,     0,     0,      0,     0},
+
+    { 23751, 20475, 17550,  14950, 12650,
+      10626,  8855,  7315,   5985,  4845,
+       3876,  3060,  2380,   1820,  1365,
+       1001,   715,   495,    330,   210,
+        126,    70,    35,     15,     5,
+          1,     0,     0,      0,     0},
+
+    {  3654,  3276,  2925,   2600,  2300,
+       2024,  1771,  1540,   1330,  1140,
+        969,   816,   680,    560,   455,
+        364,   286,   220,    165,   120,
+         84,    56,    35,     20,    10,
+          4,     1,     0,      0,     0},
+
+    {   406,   378,   351,    325,   300,
+        276,   253,   231,    210,   190,
+        171,   153,   136,    120,   105,
+         91,    78,    66,     55,    45,
+         36,    28,    21,     15,    10,
+          6,     3,     1,      0,     0},
+
+    {    29,    28,    27,     26,    25,
+         24,    23,    22,     21,    20,
+         19,    18,    17,     16,    15,
+         14,    13,    12,     11,    10,
+          9,     8,     7,      6,     5,
+          4,     3,     2,      1,     0},
+
+    {     1,     1,     1,      1,     1,
+          1,     1,     1,      1,     1,
+          1,     1,     1,      1,     1,
+          1,     1,     1,      1,     1,
+          1,     1,     1,      1,     1,
+          1,     1,     1,      1,     1},
+};
+
+static const int16_t pitch_contrib[340] = {
+    60,     0,  0,  2489, 60,     0,  0,  5217,
+     1,  6171,  0,  3953,  0, 10364,  1,  9357,
+    -1,  8843,  1,  9396,  0,  5794, -1, 10816,
+     2, 11606, -2, 12072,  0,  8616,  1, 12170,
+     0, 14440,  0,  7787, -1, 13721,  0, 18205,
+     0, 14471,  0, 15807,  1, 15275,  0, 13480,
+    -1, 18375, -1,     0,  1, 11194, -1, 13010,
+     1, 18836, -2, 20354,  1, 16233, -1,     0,
+    60,     0,  0, 12130,  0, 13385,  1, 17834,
+     1, 20875,  0, 21996,  1,     0,  1, 18277,
+    -1, 21321,  1, 13738, -1, 19094, -1, 20387,
+    -1,     0,  0, 21008, 60,     0, -2, 22807,
+     0, 15900,  1,     0,  0, 17989, -1, 22259,
+     1, 24395,  1, 23138,  0, 23948,  1, 22997,
+     2, 22604, -1, 25942,  0, 26246,  1, 25321,
+     0, 26423,  0, 24061,  0, 27247, 60,     0,
+    -1, 25572,  1, 23918,  1, 25930,  2, 26408,
+    -1, 19049,  1, 27357, -1, 24538, 60,     0,
+    -1, 25093,  0, 28549,  1,     0,  0, 22793,
+    -1, 25659,  0, 29377,  0, 30276,  0, 26198,
+     1, 22521, -1, 28919,  0, 27384,  1, 30162,
+    -1,     0,  0, 24237, -1, 30062,  0, 21763,
+     1, 30917, 60,     0,  0, 31284,  0, 29433,
+     1, 26821,  1, 28655,  0, 31327,  2, 30799,
+     1, 31389,  0, 32322,  1, 31760, -2, 31830,
+     0, 26936, -1, 31180,  1, 30875,  0, 27873,
+    -1, 30429,  1, 31050,  0,     0,  0, 31912,
+     1, 31611,  0, 31565,  0, 25557,  0, 31357,
+    60,     0,  1, 29536,  1, 28985, -1, 26984,
+    -1, 31587,  2, 30836, -2, 31133,  0, 30243,
+    -1, 30742, -1, 32090, 60,     0,  2, 30902,
+    60,     0,  0, 30027,  0, 29042, 60,     0,
+     0, 31756,  0, 24553,  0, 25636, -2, 30501,
+    60,     0, -1, 29617,  0, 30649, 60,     0,
+     0, 29274,  2, 30415,  0, 27480,  0, 31213,
+    -1, 28147,  0, 30600,  1, 31652,  2, 29068,
+    60,     0,  1, 28571,  1, 28730,  1, 31422,
+     0, 28257,  0, 24797, 60,     0,  0,     0,
+    60,     0,  0, 22105,  0, 27852, 60,     0,
+    60,     0, -1, 24214,  0, 24642,  0, 23305,
+    60,     0, 60,     0,  1, 22883,  0, 21601,
+    60,     0,  2, 25650, 60,     0, -2, 31253,
+    -2, 25144,  0, 17998
+};
+
+/* Number of non-zero pulses in the MP-MLQ excitation */
+static const int8_t pulses[4] = {6, 5, 6, 5};
+
+/* Size of the MP-MLQ fixed excitation codebooks */
+static const int32_t max_pos[4] = {593775, 142506, 593775, 142506};
+
+static const int16_t fixed_cb_gain[GAIN_LEVELS] = {
+      1,    2,    3,    4,    6,    9,   13,   18,
+     26,   38,   55,   80,  115,  166,  240,  348,
+    502,  726, 1050, 1517, 2193, 3170, 4582, 6623,
+};
+
+static const int16_t adaptive_cb_gain85[85 * 20] = {
+        0,      0,      0,      0,      0,      0,      0,      0,
+        0,      0,      0,      0,      0,      0,      0,      0,
+        0,      0,      0,      0,    800,   1496,    167,   -256,
+     -338,    -39,   -136,     -1,     -4,     -6,    -73,     -8,
+      -15,     12,     23,      2,     16,     30,      3,     -5,
+     -462,   -686,    493,   2575,    311,    -13,    -28,    -14,
+     -404,     -5,    -19,     13,     20,     72,    107,    -77,
+        8,     13,     -9,    -48,   1483,    144,    784,    928,
+     1243,   -134,     -1,    -37,    -52,    -94,    -13,    -71,
+       -6,    -84,     -8,    -44,   -112,    -10,    -59,    -70,
+      -77,    275,   3522,   1056,  -1254,      0,     -4,   -757,
+      -68,    -95,      1,     16,    -59,      4,    -17,   -227,
+       -5,     21,    269,     80,   -125,    -40,   -264,    381,
+     5027,      0,      0,     -4,     -8,  -1542,      0,     -2,
+        0,      2,      0,      6,     38,     12,     81,   -117,
+      138,    332,   2215,   2574,   1339,     -1,     -6,   -299,
+     -404,   -109,     -2,    -18,    -44,    -21,    -52,   -348,
+      -11,    -27,   -181,   -210,   3685,   2883,   -887,    866,
+    -1639,   -828,   -507,    -48,    -45,   -164,   -648,    199,
+      156,   -194,   -152,     46,    368,    288,    -88,     86,
+     1396,   2146,   2235,    345,    942,   -118,   -281,   -305,
+       -7,    -54,   -182,   -190,   -292,    -29,    -45,    -47,
+      -80,   -123,   -128,    -19,     13,   4475,   3549,   -804,
+     -655,      0,  -1222,   -768,    -39,    -26,     -3,     -2,
+     -969,      0,    219,    174,      0,    179,    141,    -32,
+     -724,    254,    242,   6049,   2462,    -32,     -3,     -3,
+    -2233,   -370,     11,     10,     -3,    267,    -94,    -89,
+      108,    -38,    -36,   -909,    626,  -1713,   6121,   4561,
+    -1061,    -23,   -179,  -2287,  -1270,    -68,     65,   -233,
+      640,   -174,    477,  -1704,     40,   -111,    396,    295,
+     -350,   1391,   7985,    511,   -405,     -7,   -118,  -3892,
+      -15,    -10,     29,    170,   -678,     10,    -43,   -249,
+       -8,     34,    197,     12,   3144,   -529,    608,   2530,
+     3878,   -603,    -17,    -22,   -390,   -918,    101,   -116,
+       19,   -485,     81,    -93,   -744,    125,   -144,   -599,
+     2589,   -689,   3045,   5603,   -404,   -409,    -29,   -566,
+    -1916,    -10,    108,   -481,    128,   -885,    235,  -1041,
+       63,    -17,     75,    138,   3107,    513,   1374,  -3594,
+    -4922,   -589,    -16,   -115,   -788,  -1478,    -97,   -260,
+      -43,    681,    112,    301,    933,    154,    413,  -1079,
+     2468,   6010,   1107,   -390,   1961,   -372,  -2204,    -74,
+       -9,   -234,   -905,   -166,   -406,     58,    143,     26,
+     -295,   -719,   -132,     46,   4773,   2766,   2368,   4862,
+    -4044,  -1390,   -467,   -342,  -1443,   -998,   -806,   -690,
+     -399,  -1416,   -821,   -702,   1178,    682,    584,   1200,
+     1665,  -1879,   1443,   1701,   8562,   -169,   -215,   -127,
+     -176,  -4475,    190,   -146,    165,   -172,    195,   -149,
+     -870,    982,   -754,   -889,   2716,   9011,  -1007,    755,
+    -1785,   -450,  -4956,    -61,    -34,   -194,  -1493,    167,
+      554,   -125,   -415,     46,    296,    982,   -109,     82,
+    -2727,   7548,   1285,    938,   3420,   -453,  -3478,   -100,
+      -53,   -714,   1256,    213,   -592,    156,   -432,    -73,
+      569,  -1576,   -268,   -196,   3677,    882,   4050,   1202,
+     2323,   -825,    -47,  -1001,    -88,   -329,   -198,   -909,
+     -218,   -269,    -64,   -297,   -521,   -125,   -574,   -170,
+     2046,   -753,    122,  10102,    603,   -255,    -34,      0,
+    -6229,    -22,     94,    -15,      5,  -1261,    464,    -75,
+      -75,     27,     -4,   -372,    449,  -1815,  10690,   3870,
+     -527,    -12,   -201,  -6976,   -914,    -16,     49,   -293,
+     1184,   -106,    428,  -2525,     14,    -58,    344,    124,
+     -941,   2352,   5049,   3650,   2637,    -54,   -337,  -1556,
+     -813,   -424,    135,    290,   -725,    209,   -524,  -1125,
+      151,   -378,   -812,   -587,  -1879,    796,   3117,   9569,
+     -404,   -215,    -38,   -593,  -5589,     -9,     91,    357,
+     -151,   1097,   -464,  -1821,    -46,     19,     76,    236,
+    -1715,   2043,  -2096,   9946,   4001,   -179,   -254,   -268,
+    -6038,   -977,    213,   -219,    261,   1041,  -1240,   1272,
+      418,   -498,    511,  -2429,  -5772,   -618,  -3921,    284,
+    -3155,  -2033,    -23,   -938,     -4,   -607,   -218,  -1381,
+     -148,    100,     10,     68,  -1111,   -119,   -755,     54,
+      382,   4748,   8003,  -2064,   2198,     -8,  -1376,  -3909,
+     -260,   -294,   -110,   -186,  -2319,     48,    598,   1008,
+      -51,   -637,  -1073,    277,   -867,   3015,  11926,  -1675,
+      947,    -45,   -555,  -8681,   -171,    -54,    159,    631,
+    -2195,    -88,    308,   1219,     50,   -174,   -690,     96,
+    -4933,   -432,   6757,   3771,   1352,  -1485,    -11,  -2786,
+     -867,   -111,   -130,   2034,    178,   1135,     99,  -1555,
+      407,     35,   -557,   -311,    152,   9726,   4231,  -1928,
+     1490,     -1,  -5774,  -1092,   -226,   -135,    -90,    -39,
+    -2511,     17,   1144,    498,    -13,   -884,   -384,    175,
+     2512,    193,   9033,   5361,  -3148,   -385,     -2,  -4980,
+    -1754,   -605,    -29,  -1385,   -106,   -822,    -63,  -2956,
+      482,     37,   1735,   1030,   8464,   2844,     12,    549,
+     2132,  -4373,   -493,      0,    -18,   -277,  -1469,     -6,
+       -2,   -284,    -95,      0,  -1101,   -370,     -1,    -71,
+     2141,  -2602,   7166,   9046,  -1350,   -279,   -413,  -3134,
+    -4994,   -111,    340,   -936,   1138,  -1182,   1436,  -3957,
+      176,   -214,    590,    745,   -244,    278,  13307,   1227,
+     -161,     -3,     -4, -10808,    -91,     -1,      4,    198,
+     -226,     18,    -20,   -997,     -2,      2,    131,     12,
+    -1947,   8217,   6269,    917,  -2559,   -231,  -4121,  -2399,
+      -51,   -399,    976,    745,  -3144,    108,   -460,   -350,
+     -304,   1283,    979,    143,  -1810,   2061,  -2781,   6056,
+    10058,   -200,   -259,   -472,  -2238,  -6174,    227,   -307,
+      349,    669,   -761,   1028,   1111,  -1265,   1707,  -3717,
+     7827,   9161,  -3409,   2473,  -1510,  -3739,  -5122,   -709,
+     -373,   -139,  -4376,   1628,   1906,  -1181,  -1382,    514,
+      721,    844,   -314,    228,  -1430,   8313,   9541,  -2955,
+     1626,   -124,  -4218,  -5556,   -533,   -161,    725,    832,
+    -4841,   -257,   1499,   1721,    142,   -825,   -947,    293,
+     2819,  -4247,   5391,   8673,   2756,   -485,  -1101,  -1774,
+    -4591,   -463,    730,   -927,   1397,  -1492,   2248,  -2854,
+     -474,    714,   -907,  -1459,    141,  14552,    690,    257,
+     -112,     -1, -12926,    -29,     -4,      0,   -125,     -5,
+     -613,     -2,   -228,    -10,      0,     99,      4,      1,
+    11938,  -1859,   1806,   -962,   -884,  -8699,   -211,   -199,
+      -56,    -47,   1355,  -1316,    205,    701,   -109,    106,
+      644,   -100,     97,    -51,   3728,   1982,   2264,   4584,
+     3131,   -848,   -239,   -312,  -1282,   -598,   -451,   -515,
+     -273,  -1043,   -554,   -633,   -712,   -378,   -432,   -876,
+    -1181,    766,    720,  14303,   -216,    -85,    -35,    -31,
+   -12486,     -2,     55,     51,    -33,   1031,   -668,   -628,
+      -15,     10,      9,    189,  -4385,   4826,  10112,   1569,
+     3388,  -1173,  -1421,  -6242,   -150,   -700,   1291,   2706,
+    -2979,    420,   -462,   -969,    906,   -998,  -2091,   -324,
+     -448,   1932,  15591,  -1842,    657,    -12,   -227, -14837,
+     -207,    -26,     52,    427,  -1838,    -50,    217,   1753,
+       18,    -77,   -626,     74,  -4141,   1844,   3962,   5517,
+     6220,  -1046,   -207,   -958,  -1858,  -2361,    466,   1001,
+     -446,   1394,   -621,  -1334,   1572,   -700,  -1504,  -2094,
+      729,  -2299,  14755,   3657,   -952,    -32,   -322, -13288,
+     -816,    -55,    102,   -656,   2071,   -162,    513,  -3294,
+       42,   -133,    857,    212,  -1385,   5801,  13339,  -3137,
+     1344,   -117,  -2054, -10861,   -600,   -110,    490,   1127,
+    -4723,   -265,   1111,   2554,    113,   -476,  -1094,    257,
+     4710,   9661,   1073,  -2467,   3274,  -1354,  -5697,    -70,
+     -371,   -654,  -2777,   -308,   -633,    709,   1455,    161,
+     -941,  -1930,   -214,    493,   1843,  -3624,  12422,   6898,
+    -1559,   -207,   -802,  -9419,  -2904,   -148,    407,  -1397,
+     2748,   -775,   1526,  -5230,    175,   -344,   1182,    656,
+     1433,   2394,   2507,   1380,   8780,   -125,   -349,   -383,
+     -116,  -4705,   -209,   -219,   -366,   -120,   -201,   -211,
+     -768,  -1283,  -1343,   -740,  -1712,  12915,   5883,  -2197,
+      991,   -179, -10181,  -2112,   -294,    -60,   1350,    615,
+    -4638,   -229,   1732,    789,    103,   -781,   -356,    133,
+    15072,   2158,  -1245,    910,   -496, -13865,   -284,    -94,
+      -50,    -15,  -1986,   1145,    164,   -837,   -119,     69,
+      456,     65,    -37,     27,   4655,   7319,   4916,    586,
+    -3381,  -1322,  -3270,  -1475,    -20,   -697,  -2079,  -1396,
+    -2196,   -166,   -261,   -175,    960,   1510,   1014,    120,
+     1191,  -2140,   5120,  13498,  -1418,    -86,   -279,  -1600,
+   -11121,   -122,    155,   -372,    669,   -981,   1763,  -4218,
+      103,   -185,    443,   1168,  -1530,   -817,   8191,   9632,
+    -1452,   -143,    -40,  -4095,  -5663,   -128,    -76,    765,
+      408,    900,    480,  -4815,   -135,    -72,    726,    854,
+    -3236,    607,   1696,  -2106,  11485,   -639,    -22,   -175,
+     -270,  -8051,    119,    335,    -62,   -416,     78,    218,
+     2268,   -425,  -1189,   1476,   3203,  -1903,   -837,   9679,
+     7057,   -626,   -221,    -42,  -5718,  -3039,    372,    163,
+      -97,  -1892,   1124,    494,  -1380,    819,    360,  -4169,
+      213,   -655,  17015,    620,   -384,     -2,    -26, -17671,
+      -23,     -9,      8,   -221,    681,     -8,     24,   -644,
+        5,    -15,    399,     14,   5088,     35,  -3339,   3726,
+     8488,  -1580,      0,   -680,   -847,  -4397,    -10,   1037,
+        7,  -1157,     -8,    759,  -2636,    -18,   1730,  -1930,
+     -988,   1454,  -2688,  15039,   2682,    -59,   -129,   -441,
+   -13805,   -439,     87,   -162,    238,    907,  -1335,   2467,
+      161,   -238,    440,  -2462,  -4865,  -2842,    -53,   5495,
+     6523,  -1445,   -493,      0,  -1843,  -2597,   -844,    -16,
+       -9,   1632,    953,     18,   1937,   1131,     21,  -2188,
+     3076,  15069,  -2914,   1810,   -971,   -577, -13860,   -518,
+     -200,    -57,  -2829,    547,   2680,   -339,  -1665,    322,
+      182,    893,   -172,    107,   1311,   5355,  11054,   2299,
+    -3654,   -105,  -1750,  -7458,   -322,   -814,   -428,   -885,
+    -3613,   -184,   -751,  -1551,    292,   1194,   2465,    512,
+     4035,   5619,   4618,   1815,   1912,   -994,  -1927,  -1301,
+     -201,   -223,  -1384,  -1137,  -1583,   -447,   -622,   -511,
+     -471,   -656,   -539,   -211,  -2131,   2754,  -4501,  12879,
+     7432,   -277,   -463,  -1236, -10124,  -3371,    358,   -585,
+      756,   1675,  -2165,   3538,    967,  -1249,   2042,  -5842,
+     5618,   -515,   3219,  -4149,   4857,  -1926,    -16,   -632,
+    -1050,  -1440,    176,  -1104,    101,   1422,   -130,    815,
+    -1666,    152,   -954,   1230,   1838,  -1709,   1139,  16867,
+      716,   -206,   -178,    -79, -17366,    -31,    191,   -127,
+      118,  -1892,   1759,  -1173,    -80,     74,    -49,   -737,
+     1978,  -3845,  10050,  11854,  -2492,   -238,   -902,  -6164,
+    -8576,   -379,    464,  -1213,   2358,  -1431,   2782,  -7271,
+      301,   -585,   1529,   1803,  -2600,  11246,  11289,  -3647,
+     1463,   -412,  -7720,  -7778,   -812,   -130,   1784,   1791,
+    -7749,   -578,   2504,   2513,    232,  -1004,  -1008,    325,
+     3442,    907,   2725,   8970,   3638,   -723,    -50,   -453,
+    -4911,   -808,   -190,   -572,   -150,  -1884,   -496,  -1492,
+     -764,   -201,   -605,  -1992,   -126,  17498,   3481,  -2003,
+     1090,      0, -18689,   -739,   -244,    -72,    135,     26,
+    -3717,    -15,   2139,    425,      8,  -1165,   -231,    133,
+    -1814,   1048,  -2164,   4070,  16272,   -200,    -67,   -285,
+    -1011, -16160,    116,   -239,    138,    450,   -260,    537,
+     1801,  -1041,   2149,  -4042,   9354,  12580,  -1883,    962,
+     -617,  -5341,  -9660,   -216,    -56,    -23,  -7183,   1075,
+     1446,   -549,   -738,    110,    352,    474,    -71,     36,
+     1708,   4199,   7387,   6335,   1003,   -178,  -1076,  -3330,
+    -2449,    -61,   -437,   -770,  -1893,   -660,  -1623,  -2856,
+     -104,   -257,   -452,   -388,  -2624,   5623,  17310,  -2353,
+      592,   -420,  -1930, -18288,   -338,    -21,    900,   2772,
+    -5941,   -376,    807,   2486,     94,   -203,   -625,     85,
+     1211,   -850,   1193,  -1926,  15992,    -89,    -44,    -86,
+     -226, -15609,     62,    -88,     61,    142,   -100,    140,
+    -1182,    830,  -1165,   1880,   3983,  -2054,  11506,    -19,
+     3622,   -968,   -257,  -8080,      0,   -801,    499,  -2797,
+     1442,      4,     -2,     13,   -880,    454,  -2544,      4,
+     -786,  -1354,  16092,   7246,  -1665,    -37,   -111, -15805,
+    -3205,   -169,    -65,    772,   1330,    348,    599,  -7117,
+      -80,   -137,   1636,    736,  -4316,   -511,   6674,  11665,
+     4633,  -1137,    -15,  -2719,  -8305,  -1310,   -134,   1758,
+      208,   3073,    364,  -4752,   1220,    144,  -1887,  -3299,
+     7912,   4557,   1937,   1885,   7037,  -3821,  -1267,   -229,
+     -216,  -3022,  -2200,   -935,   -538,   -910,   -524,   -222,
+    -3398,  -1957,   -832,   -809,   3434,   2967,   5867,   8196,
+     8766,   -720,   -537,  -2101,  -4100,  -4690,   -622,  -1230,
+    -1062,  -1718,  -1484,  -2935,  -1837,  -1588,  -3139,  -4385,
+     5881,   9176,   8119,   3934,   3355,  -2111,  -5139,  -4023,
+     -944,   -687,  -3294,  -2914,  -4547,  -1412,  -2203,  -1949,
+    -1204,  -1879,  -1662,   -805
+};
+
+static const int16_t adaptive_cb_gain170[170 * 20] = {
+        0,      0,      0,      0,      0,      0,      0,      0,
+        0,      0,      0,      0,      0,      0,      0,      0,
+        0,      0,      0,      0,    776,    212,    715,    670,
+      809,    -36,     -2,    -31,    -27,    -39,    -10,    -33,
+       -9,    -31,     -8,    -29,    -38,    -10,    -35,    -33,
+     1296,   1316,   -168,   -320,   -815,   -102,   -105,     -1,
+       -6,    -40,   -104,     13,     13,     25,     25,     -3,
+       64,     65,     -8,    -15,   -589,    680,   2478,    308,
+     -596,    -21,    -28,   -375,     -5,    -21,     24,     89,
+     -102,     11,    -12,    -46,    -21,     24,     90,     11,
+     -735,   -487,     -5,   2948,    468,    -33,    -14,      0,
+     -530,    -13,    -21,      0,      0,    132,     87,      0,
+       21,     13,      0,    -84,   1042,   1730,   1068,    333,
+      626,    -66,   -182,    -69,     -6,    -23,   -110,    -67,
+     -112,    -21,    -35,    -21,    -39,    -66,    -40,    -12,
+      486,   -769,   4074,   2825,  -1107,    -14,    -36,  -1013,
+     -487,    -74,     22,   -120,    191,    -83,    132,   -702,
+       32,    -52,    275,    191,   1521,   -767,   -124,   4320,
+     1026,   -141,    -35,      0,  -1139,    -64,     71,     11,
+       -5,   -401,    202,     32,    -95,     48,      7,   -270,
+     2425,   1267,   3439,    -91,  -1166,   -359,    -98,   -722,
+        0,    -83,   -187,   -509,   -266,     13,      7,     19,
+      172,     90,    244,     -6,  -1251,    975,    173,   4039,
+     2005,    -95,    -58,     -1,   -996,   -245,     74,     13,
+      -10,    308,   -240,    -42,    153,   -119,    -21,   -494,
+     1820,    632,   1322,   2062,   1031,   -202,    -24,   -106,
+     -259,    -64,    -70,   -146,    -51,   -229,    -79,   -166,
+     -114,    -39,    -83,   -129,   -447,   4904,    244,   -315,
+    -2038,    -12,  -1467,     -3,     -6,   -253,    134,      6,
+      -73,     -8,     94,      4,    -55,    610,     30,    -39,
+     -208,  -1102,    463,   -448,   5653,     -2,    -74,    -13,
+      -12,  -1950,    -14,      5,     31,     -5,    -30,     12,
+       71,    380,   -159,    154,   4739,   2600,  -1864,    856,
+    -1554,  -1371,   -412,   -212,    -44,   -147,   -752,    539,
+      295,   -247,   -135,     97,    449,    246,   -176,     81,
+     1894,   3533,     35,    -26,   2145,   -219,   -762,      0,
+        0,   -280,   -408,     -4,     -7,      3,      5,      0,
+     -248,   -462,     -4,      3,  -2699,   1841,   4072,   2443,
+     1582,   -444,   -207,  -1012,   -364,   -152,    303,    670,
+     -457,    402,   -274,   -607,    260,   -177,   -393,   -236,
+     -844,   3358,   6106,  -1059,   -537,    -43,   -688,  -2275,
+      -68,    -17,    173,    314,  -1251,    -54,    217,    395,
+      -27,    110,    200,    -34,   1251,   1016,   3020,   2210,
+     1445,    -95,    -63,   -556,   -298,   -127,    -77,   -230,
+     -187,   -168,   -137,   -407,   -110,    -89,   -266,   -194,
+     2099,   2277,   4038,   3533,  -2870,   -269,   -316,   -995,
+     -762,   -503,   -291,   -517,   -561,   -452,   -491,   -871,
+      367,    399,    707,    619,    400,  -1114,   8516,   2422,
+    -1117,     -9,    -75,  -4426,   -358,    -76,     27,   -208,
+      579,    -59,    164,  -1259,     27,    -75,    580,    165,
+    -4398,  -2011,   3912,  -2407,   2258,  -1180,   -247,   -934,
+     -353,   -311,   -540,   1050,    480,   -646,   -295,    575,
+      606,    277,   -539,    331,   1767,  -1447,   4240,   6160,
+     -757,   -190,   -127,  -1097,  -2316,    -35,    156,   -457,
+      374,   -664,    544,  -1594,     81,    -66,    195,    284,
+     1594,  -1463,   1035,   6938,   1920,   -155,   -130,    -65,
+    -2938,   -225,    142,   -100,     92,   -675,    619,   -438,
+     -186,    171,   -121,   -813,   -562,   4716,   4085,   -591,
+     2421,    -19,  -1357,  -1018,    -21,   -357,    162,    140,
+    -1175,    -20,    170,    147,     83,   -696,   -603,     87,
+     1552,   8778,   -935,    354,  -1424,   -147,  -4703,    -53,
+       -7,   -123,   -831,     88,    501,    -33,   -189,     20,
+      134,    763,    -81,     30,   4831,  -4431,     41,  -1479,
+    -2976,  -1424,  -1198,      0,   -133,   -540,   1306,    -12,
+       11,    436,   -400,      3,    877,   -804,      7,   -268,
+     2090,   1192,   1006,   1645,   4853,   -266,    -86,    -61,
+     -165,  -1437,   -152,   -128,    -73,   -210,   -119,   -101,
+     -619,   -353,   -298,   -487,   2386,   5712,   1426,    -94,
+     1350,   -347,  -1991,   -124,      0,   -111,   -832,   -207,
+     -497,     13,     32,      8,   -196,   -470,   -117,      7,
+    -1349,   1091,   1659,   8891,    313,   -111,    -72,   -168,
+    -4825,     -5,     89,    136,   -110,    732,   -592,   -900,
+       25,    -20,    -31,   -170,   9980,    916,   -381,   -808,
+       88,  -6080,    -51,     -8,    -39,      0,   -558,    232,
+       21,    492,     45,    -18,    -53,     -4,      2,      4,
+     2338,  -1031,   -248,   3928,   6484,   -333,    -64,     -3,
+     -942,  -2566,    147,     35,    -15,   -560,    247,     59,
+     -925,    408,     98,  -1555,   6166,  -1240,   -337,   3672,
+    -1277,  -2320,    -93,     -6,   -823,    -99,    466,    126,
+      -25,  -1382,    278,     75,    480,    -96,    -26,    286,
+     4377,   -132,  -2588,   1701,   4865,  -1169,     -1,   -409,
+     -176,  -1444,     35,    691,    -20,   -454,     13,    268,
+    -1299,     39,    768,   -505,   2594,   3295,   3944,   1481,
+      682,   -410,   -662,   -949,   -133,    -28,   -521,   -624,
+     -793,   -234,   -297,   -356,   -108,   -137,   -164,    -61,
+     4151,    624,    815,   4485,   2229,  -1052,    -23,    -40,
+    -1228,   -303,   -158,   -206,    -31,  -1136,   -170,   -223,
+     -565,    -84,   -111,   -610,  -3575,   -361,   4924,   2791,
+     4698,   -780,     -7,  -1480,   -475,  -1347,    -78,   1074,
+      108,    609,     61,   -839,   1025,    103,  -1412,   -800,
+    -2518,   3791,   8623,    315,   2465,   -387,   -877,  -4538,
+       -6,   -370,    582,   1325,  -1995,     48,    -73,   -166,
+      378,   -570,  -1297,    -47,   -691,   2989,   9957,   -421,
+    -1142,    -29,   -545,  -6051,    -10,    -79,    126,    420,
+    -1817,    -17,     76,    256,    -48,    208,    694,    -29,
+    -1918,    104,  -3190,  -3410,  -4440,   -224,      0,   -621,
+     -709,  -1203,     12,   -373,     20,   -399,     21,   -664,
+     -519,     28,   -864,   -924,  -3359,  -1668,   1854,   6939,
+     1430,   -688,   -169,   -209,  -2939,   -124,   -341,    380,
+      188,   1422,    706,   -785,    293,    145,   -161,   -606,
+       42,   9706,   3164,   -952,    907,      0,  -5750,   -611,
+      -55,    -50,    -25,     -8,  -1874,      2,    564,    183,
+       -2,   -537,   -175,     52,   1607,    785,   2862,   4327,
+     3307,   -157,    -37,   -500,  -1143,   -667,    -77,   -280,
+     -137,   -424,   -207,   -756,   -324,   -158,   -577,   -873,
+     6801,   3416,   2227,   1682,  -3217,  -2823,   -712,   -302,
+     -172,   -631,  -1418,   -924,   -464,   -698,   -350,   -228,
+     1335,    670,    437,    330,   3459,   3898,    364,   7841,
+    -2640,   -730,   -927,     -8,  -3753,   -425,   -823,    -76,
+      -86,  -1655,  -1865,   -174,    557,    628,     58,   1263,
+    -5902,  -3458,  -2465,  -1886,   4334,  -2126,   -730,   -371,
+     -217,  -1146,  -1245,   -888,   -520,   -679,   -398,   -283,
+     1561,    915,    652,    499,  -3710,   1133,   7849,   3443,
+     -215,   -840,    -78,  -3760,   -723,     -2,    256,   1777,
+     -543,    779,   -238,  -1649,    -48,     14,    103,     45,
+     4132,   2828,      2,  -4212,  -4116,  -1042,   -488,      0,
+    -1083,  -1034,   -713,      0,      0,   1062,    727,      0,
+     1038,    710,      0,  -1058,   5875,   8496,  -1796,   1376,
+    -1786,  -2107,  -4406,   -197,   -115,   -194,  -3047,    644,
+      931,   -493,   -713,    150,    640,    926,   -195,    150,
+     3143,   3483,   3546,   -793,   4489,   -603,   -740,   -767,
+      -38,  -1230,   -668,   -680,   -754,    152,    168,    171,
+     -861,   -954,   -971,    217,   2845,   7965,   3695,  -5432,
+     3978,   -494,  -3873,   -833,  -1801,   -966,  -1383,   -641,
+    -1796,    943,   2641,   1225,   -691,  -1934,   -897,   1319,
+     1538,    150,   7139,   2049,   3097,   -144,     -1,  -3110,
+     -256,   -585,    -14,   -670,    -65,   -192,    -18,   -892,
+     -290,    -28,  -1349,   -387,    618,   7520,   4729,   -238,
+    -3373,    -23,  -3452,  -1365,     -3,   -694,   -283,   -178,
+    -2170,      8,    109,     68,    127,   1548,    973,    -49,
+     2965,  -3013,   7912,   7076,  -1997,   -536,   -554,  -3821,
+    -3056,   -243,    545,  -1431,   1455,  -1280,   1301,  -3417,
+      361,   -367,    964,    862,   2443,   -929,  -1113,   9677,
+     4138,   -364,    -52,    -75,  -5716,  -1045,    138,    166,
+      -63,  -1443,    549,    657,   -617,    234,    281,  -2444,
+     1966,   3309,  10085,  -3399,   2105,   -236,   -668,  -6207,
+     -705,   -270,   -397,  -1210,  -2037,    408,    686,   2092,
+     -252,   -425,  -1295,    436,   -112,  -1368,   8868,   4822,
+     2048,      0,   -114,  -4800,  -1419,   -256,     -9,     61,
+      740,     33,    402,  -2610,     14,    171,  -1108,   -602,
+    -2597,    438,  -1839,   6229,   7266,   -411,    -11,   -206,
+    -2368,  -3223,     69,   -291,     49,    987,   -166,    699,
+     1152,   -194,    816,  -2763,   3454,    553,   9127,   4946,
+    -5596,   -728,    -18,  -5084,  -1493,  -1911,   -116,  -1924,
+     -308,  -1042,   -166,  -2755,   1179,    188,   3117,   1689,
+     -532,   -663,  12262,   2495,  -1004,    -17,    -26,  -9177,
+     -380,    -61,    -21,    398,    496,     81,    101,  -1867,
+      -32,    -40,    751,    152,  -2100,   1317,  -1509,  11425,
+     2997,   -269,   -105,   -139,  -7967,   -548,    168,   -193,
+      121,   1464,   -918,   1052,    384,   -240,    276,  -2090,
+     1193,  -2697,  11259,   5373,   -763,    -86,   -444,  -7737,
+    -1762,    -35,    196,   -819,   1853,   -391,    884,  -3692,
+       55,   -125,    525,    250,   2405,   -471,  11079,    203,
+      782,   -353,    -13,  -7491,     -2,    -37,     69,  -1626,
+      318,    -29,      5,   -137,   -114,     22,   -529,     -9,
+    -1871,   5685,  11290,  -2662,   1353,   -213,  -1972,  -7780,
+     -432,   -111,    649,   1289,  -3917,   -304,    923,   1834,
+      154,   -469,   -932,    220,  -3768,   5927,  -3093,   5041,
+     5212,   -866,  -2144,   -584,  -1551,  -1658,   1363,   -711,
+     1119,   1159,  -1824,    951,   1198,  -1885,    984,  -1603,
+    -2546,   9502,   5969,  -2440,   1928,   -395,  -5511,  -2175,
+     -363,   -226,   1477,    927,  -3462,   -379,   1415,    889,
+      299,  -1118,   -702,    287,  -4963,   3568,   4592,   5508,
+     3451,  -1503,   -777,  -1287,  -1851,   -727,   1080,   1391,
+    -1000,   1668,  -1199,  -1543,   1045,   -751,   -967,  -1160,
+     1745,  -2586,   3983,  10899,  -1551,   -186,   -408,   -968,
+    -7250,   -146,    275,   -424,    628,  -1161,   1720,  -2649,
+      165,   -244,    377,   1032,    867,   -456,   -727,   3369,
+    11822,    -45,    -12,    -32,   -692,  -8531,     24,     38,
+      -20,   -178,     93,    149,   -625,    329,    525,  -2431,
+     7535,   2422,   1926,   1405,   1599,  -3466,   -358,   -226,
+     -120,   -156,  -1114,   -886,   -284,   -646,   -207,   -165,
+     -735,   -236,   -188,   -137,   1041,   -735,   -142,  13209,
+     1515,    -66,    -33,     -1, -10649,   -140,     46,      9,
+       -6,   -839,    593,    114,    -96,     68,     13,  -1222,
+     7950,   6745,  -1444,  -1008,   2721,  -3857,  -2777,   -127,
+      -62,   -452,  -3273,    700,    594,    489,    415,    -88,
+    -1320,  -1120,    239,    167,  -4754,  -1379,   4522,   -578,
+    -5733,  -1379,   -116,  -1248,    -20,  -2006,   -400,   1312,
+      380,   -167,    -48,    159,  -1663,   -482,   1582,   -202,
+     3220,   5978,   5923,   2430,  -2689,   -633,  -2181,  -2141,
+     -360,   -441,  -1175,  -1164,  -2161,   -477,   -886,   -878,
+      528,    981,    972,    398,    377,   1312,  13978,  -1470,
+      677,     -8,   -105, -11925,   -132,    -28,    -30,   -321,
+    -1119,     33,    117,   1254,    -15,    -54,   -577,     60,
+    -3435,   6770,    314,   -885,   5686,   -720,  -2797,     -6,
+      -47,  -1973,   1419,     65,   -129,   -185,    366,     16,
+     1192,  -2349,   -109,    307,   3171,   8774,  -2260,   2679,
+     3069,   -613,  -4699,   -312,   -438,   -575,  -1698,    437,
+     1210,   -518,  -1435,    369,   -594,  -1643,    423,   -501,
+     5557,   1509,   5407,   -125,  -7386,  -1884,   -139,  -1784,
+        0,  -3330,   -511,  -1834,   -498,     42,     11,     41,
+     2505,    680,   2438,    -56,  -2838,   2595,  13228,    271,
+     1793,   -491,   -411, -10680,     -4,   -196,    449,   2291,
+    -2095,     47,    -42,   -219,    310,   -284,  -1447,    -29,
+      664,   -278,  14966,    951,   -711,    -26,     -4, -13672,
+      -55,    -30,     11,   -606,    253,    -38,     16,   -869,
+       28,    -12,    650,     41,    808,   1770,   8658,   5863,
+    -1486,    -39,   -191,  -4576,  -2098,   -134,    -87,   -427,
+     -935,   -289,   -633,  -3098,     73,    160,    785,    531,
+     3063,   1539,   2000,   -542,   9576,   -572,   -144,   -244,
+      -17,  -5597,   -287,   -374,   -188,    101,     51,     66,
+    -1790,   -900,  -1169,    317,    514,  14083,   -323,    896,
+     -891,    -16, -12106,     -6,    -49,    -48,   -442,     10,
+      277,    -28,   -770,     17,     27,    766,    -17,     48,
+      892,    158,   5237,  11057,  -1603,    -48,     -1,  -1674,
+    -7462,   -156,     -8,   -285,    -50,   -602,   -106,  -3534,
+       87,     15,    512,   1082,  -1612,   2564,  -4296,  12526,
+     5710,   -158,   -401,  -1126,  -9576,  -1990,    252,   -422,
+      672,   1232,  -1960,   3284,    561,   -893,   1497,  -4365,
+     4889,  -6878,    612,   6109,   4753,  -1459,  -2887,    -22,
+    -2277,  -1379,   2052,   -182,    257,  -1823,   2564,   -228,
+    -1418,   1995,   -177,  -1772,   3053,   -506,   2403,   9625,
+     1322,   -569,    -15,   -352,  -5655,   -106,     94,   -448,
+       74,  -1794,    297,  -1412,   -246,     40,   -194,   -777,
+     -754,  12904,   4480,  -2113,   1471,    -34, -10163,  -1225,
+     -272,   -132,    594,    206,  -3529,    -97,   1664,    577,
+       67,  -1159,   -402,    189,   4255,   1476,   5055,   2393,
+     2912,  -1105,   -132,  -1559,   -349,   -517,   -383,  -1313,
+     -455,   -621,   -215,   -738,   -756,   -262,   -898,   -425,
+    -1371,    535,   1417,  14604,   -997,   -114,    -17,   -122,
+   -13017,    -60,     44,    118,    -46,   1222,   -477,  -1263,
+      -83,     32,     86,    888,   5368,  -1744,   4083,  -1236,
+     3753,  -1758,   -185,  -1017,    -93,   -860,    571,  -1338,
+      434,    405,   -131,    308,  -1229,    399,   -935,    283,
+     1588,  -3097,  14415,   3699,  -1171,   -154,   -585, -12683,
+     -835,    -83,    300,  -1397,   2725,   -358,    699,  -3255,
+      113,   -221,   1030,    264,    212,   7989,   9471,  -3344,
+     2009,     -2,  -3895,  -5475,   -682,   -246,   -103,   -123,
+    -4618,     43,   1630,   1933,    -26,   -979,  -1161,    410,
+      856,   2294,   -627,   6930,   6929,    -44,   -321,    -24,
+    -2931,  -2930,   -119,     32,     87,   -362,   -970,    265,
+     -362,   -970,    265,  -2931,   2357,  -4187,   7162,   7683,
+     3371,   -339,  -1070,  -3131,  -3603,   -693,    602,  -1030,
+     1830,  -1105,   1963,  -3359,   -485,    861,  -1474,  -1581,
+      350,   4585,  14053,  -3819,   1218,     -7,  -1283, -12054,
+     -890,    -90,    -97,   -300,  -3933,     81,   1068,   3275,
+      -26,   -341,  -1045,    284,  -3248,   3531,    475,   2137,
+    11711,   -644,   -761,    -13,   -278,  -8372,    700,     94,
+     -102,    423,   -460,    -62,   2322,  -2524,   -340,  -1528,
+    -3017,   3852,   1725,   8440,   5257,   -555,   -905,   -181,
+    -4348,  -1686,    709,    317,   -405,   1554,  -1984,   -889,
+      968,  -1236,   -553,  -2708,   -909,   3196,  15512,  -2528,
+     1066,    -50,   -623, -14686,   -390,    -69,    177,    861,
+    -3026,   -140,    493,   2393,     59,   -208,  -1009,    164,
+      959,  -3370,   9617,   9545,  -1761,    -56,   -693,  -5645,
+    -5561,   -189,    197,   -563,   1978,   -558,   1963,  -5603,
+      103,   -362,   1034,   1026,   7575,  11796,  -4845,   3252,
+    -1703,  -3502,  -8493,  -1433,   -645,   -177,  -5454,   2240,
+     3488,  -1503,  -2341,    961,    787,   1226,   -503,    338,
+     6409,   1722,   1764,  -4191,   6015,  -2507,   -181,   -189,
+    -1072,  -2208,   -673,   -690,   -185,   1639,    440,    451,
+    -2353,   -632,   -647,   1538,  -2420,  12161,   5038,   1286,
+    -2098,   -357,  -9027,  -1549,   -100,   -268,   1796,    744,
+    -3740,    190,   -954,   -395,   -310,   1557,    645,    164,
+    -2232,  -1341,   7246,   9470,  -1977,   -304,   -109,  -3204,
+    -5474,   -238,   -182,    987,    593,   1290,    775,  -4188,
+     -269,   -161,    874,   1143,   1030,   7034,   4231,   1551,
+     3077,    -64,  -3019,  -1093,   -146,   -577,   -442,   -266,
+    -1816,    -97,   -666,   -400,   -193,  -1321,   -794,   -291,
+     5121,  11835,   -477,  -1749,   2298,  -1601,  -8549,    -13,
+     -186,   -322,  -3699,    149,    344,    546,   1264,    -50,
+     -718,  -1660,     66,    245,  -3328,   3827,   5921,   9976,
+    -1045,   -676,   -894,  -2140,  -6075,    -66,    777,   1203,
+    -1383,   2027,  -2330,  -3605,   -212,    244,    377,    636,
+     3813,   5718,  -4666,  -3412,   5674,   -887,  -1995,  -1329,
+     -710,  -1965,  -1331,   1086,   1628,    794,   1191,   -972,
+    -1320,  -1980,   1616,   1181,   1348,  -3672,  13154,   6938,
+    -1690,   -110,   -823, -10561,  -2938,   -174,    302,  -1082,
+     2948,   -570,   1555,  -5570,    139,   -379,   1357,    716,
+     2151,  -3586,   6949,  12131,  -1224,   -282,   -785,  -2947,
+    -8982,    -91,    470,   -912,   1521,  -1592,   2655,  -5145,
+      160,   -268,    519,    906,  -2889,   9647,  10276,  -2728,
+      995,   -509,  -5680,  -6445,   -454,    -60,   1701,   1812,
+    -6051,   -481,   1606,   1711,    175,   -586,   -624,    165,
+     6177,   2184,    555,   1985,   6589,  -2329,   -291,    -18,
+     -240,  -2650,   -823,   -209,    -74,   -748,   -264,    -67,
+    -2484,   -878,   -223,   -798,   -492,    391,  17166,   -681,
+      240,    -14,     -9, -17987,    -28,     -3,     11,    515,
+     -410,    -20,     16,    713,      7,     -5,   -252,     10,
+    12628,   5448,  -2630,   3011,  -2695,  -9733,  -1811,   -422,
+     -553,   -443,  -4199,   2027,    874,  -2321,  -1001,    483,
+     2077,    896,   -432,    495,  -3628,   -534,   3447,   7002,
+     6751,   -803,    -17,   -725,  -2992,  -2782,   -118,    763,
+      112,   1550,    228,  -1473,   1495,    220,  -1420,  -2885,
+    -5239,   5901,   8107,   3650,   4846,  -1675,  -2125,  -4012,
+     -813,  -1433,   1887,   2592,  -2920,   1167,  -1315,  -1806,
+     1550,  -1745,  -2398,  -1080,   6157,   6678,   4099,  -1074,
+     2348,  -2314,  -2722,  -1025,    -70,   -336,  -2509,  -1540,
+    -1670,    403,    437,    268,   -882,   -957,   -587,    153,
+     1079,  16099,    242,   -881,   1690,    -71, -15820,     -3,
+      -47,   -174,  -1060,    -16,   -238,     58,    865,     13,
+     -111,  -1661,    -25,     90,   -278,    227,  -1039,   1636,
+    16945,     -4,     -3,    -65,   -163, -17526,      3,    -17,
+       14,     27,    -22,    103,    287,   -234,   1074,  -1693,
+    15778,  -1454,    574,   -603,   -107, -15195,   -129,    -20,
+      -22,      0,   1400,   -553,     51,    581,    -53,     21,
+      103,     -9,      3,     -3,   2406,   -836,  13224,   7993,
+    -4266,   -353,    -42, -10673,  -3899,  -1111,    122,  -1942,
+      674,  -1174,    407,  -6451,    626,   -217,   3443,   2081,
+     3184,  14368,  -3336,   2255,  -1801,   -619, -12600,   -679,
+     -310,   -198,  -2793,    648,   2926,   -438,  -1977,    459,
+      350,   1580,   -366,    247,  -1698,  17076,   2504,   -539,
+     -646,   -176, -17798,   -382,    -17,    -25,   1770,    259,
+    -2610,    -55,    561,     82,    -67,    673,     98,    -21,
+     2375,   -797,  -2696,  14483,   5383,   -344,    -38,   -443,
+   -12803,  -1769,    115,    391,   -131,  -2100,    705,   2384,
+     -780,    262,    886,  -4759,  -2691,   2554,  -4520,   9573,
+    10655,   -442,   -398,  -1247,  -5594,  -6930,    419,   -742,
+      704,   1572,  -1492,   2641,   1750,  -1661,   2939,  -6226,
+    -4332,  -4399,  -1657,   4880,   7375,  -1145,  -1181,   -167,
+    -1453,  -3319,  -1163,   -438,   -444,   1290,   1310,    493,
+     1950,   1980,    745,  -2196,  -3498,   7405,   9955,   2693,
+    -2971,   -746,  -3347,  -6049,   -442,   -538,   1581,   2125,
+    -4499,    575,  -1217,  -1636,   -634,   1342,   1805,    488,
+     6717,  -3792,   7739,   2798,   3489,  -2754,   -877,  -3655,
+     -477,   -743,   1554,  -3173,   1791,  -1147,    647,  -1321,
+    -1430,    807,  -1648,   -595,   5263,   9770,   3463,   1069,
+    -3971,  -1690,  -5826,   -732,    -69,   -962,  -3138,  -1112,
+    -2065,   -343,   -637,   -226,   1275,   2368,    839,    259,
+     1243,  -2634,  16772,   1871,    332,    -94,   -423, -17169,
+     -213,     -6,    199,  -1273,   2696,   -142,    300,  -1915,
+      -25,     53,   -339,    -37,   2691,   2836,   3105,   5711,
+     4817,   -442,   -491,   -588,  -1991,  -1416,   -465,   -510,
+     -537,   -938,   -988,  -1082,   -791,   -834,   -913,  -1679,
+     4366,   2944,   7210,   3627,   1161,  -1163,   -529,  -3172,
+     -803,    -82,   -784,  -1921,  -1295,   -966,   -651,  -1596,
+     -309,   -208,   -511,   -257,  13888,   3951,   -671,  -2305,
+     3354, -11773,   -953,    -27,   -324,   -686,  -3349,    569,
+      161,   1954,    556,    -94,  -2843,   -809,    137,    472,
+     7053,   5847,   2929,   8378,  -4794,  -3036,  -2086,   -523,
+    -4284,  -1403,  -2517,  -1261,  -1045,  -3607,  -2990,  -1498,
+     2064,   1711,    857,   2451,  -2191,  12838,   9182,  -3915,
+     1617,   -293, -10059,  -5146,   -935,   -159,   1717,   1228,
+    -7195,   -523,   3068,   2194,    216,  -1267,   -906,    386,
+    -4881,  13114,   5767,   -435,   4155,  -1454, -10498,  -2030,
+      -11,  -1054,   3907,   1718,  -4616,   -129,    348,    153,
+     1238,  -3326,  -1462,    110,   7843,  -1250,    210,   7106,
+    -5203,  -3754,    -95,     -2,  -3082,  -1652,    598,   -100,
+       16,  -3402,    542,    -91,   2491,   -397,     66,   2257,
+    -2463,   8168,  14551,  -3908,   1828,   -370,  -4072, -12923,
+     -932,   -204,   1228,   2188,  -7254,   -587,   1948,   3471,
+      274,   -911,  -1623,    436,  -1579,    347,   -272,  -2735,
+    16031,   -152,     -7,     -4,   -456, -15686,     33,    -26,
+        5,   -263,     58,    -45,   1545,   -340,    266,   2676,
+    -6327,   1328,   5093,  -5079,   7617,  -2443,   -107,  -1583,
+    -1574,  -3541,    513,   1967,   -413,  -1961,    411,   1578,
+     2941,   -617,  -2367,   2361,   3286,  -4509,  11306,  11025,
+    -2623,   -659,  -1241,  -7802,  -7419,   -420,    904,  -2267,
+     3112,  -2211,   3034,  -7608,    526,   -722,   1810,   1765,
+     5567,  17853,  -3754,   1166,   -519,  -1892, -19455,   -860,
+      -83,    -16,  -6067,   1275,   4090,   -396,  -1271,    267,
+      176,    566,   -119,     37,  -2136,   -424,  15292,   5108,
+    -1648,   -278,    -10, -14273,  -1593,   -165,    -55,   1993,
+      396,    666,    132,  -4768,   -214,    -42,   1538,    514,
+     2267,  -3297,   2549,  16563,   -791,   -313,   -663,   -396,
+   -16745,    -38,    456,   -352,    513,  -2291,   3333,  -2576,
+      109,   -159,    123,    799,   3655,   1899,  -3364,   6279,
+    12510,   -815,   -220,   -690,  -2406,  -9552,   -423,    750,
+      390,  -1400,   -728,   1289,  -2791,  -1450,   2568,  -4794,
+     8052,   2285,  -6193,   5138,   6003,  -3957,   -318,  -2341,
+    -1611,  -2199,  -1123,   3044,    864,  -2525,   -716,   1942,
+    -2950,   -837,   2269,  -1882,   -386,  -2291,   7679,  15387,
+    -2723,     -9,   -320,  -3599, -14452,   -452,    -54,    181,
+     1074,    362,   2152,  -7212,    -64,   -380,   1276,   2557,
+     2777,  -1173,   3984,  13079,   2508,   -470,    -84,   -969,
+   -10440,   -384,    198,   -675,    285,  -2217,    936,  -3180,
+     -425,    179,   -610,  -2002,  -1879,   1771,  -2684,  16705,
+     1833,   -215,   -191,   -439, -17032,   -205,    203,   -308,
+      290,   1916,  -1805,   2736,    210,   -198,    300,  -1869,
+     1052,   4495,  15519,   1467,  -4032,    -67,  -1233, -14700,
+     -131,   -992,   -288,   -997,  -4257,    -94,   -402,  -1389,
+      259,   1106,   3819,    361,   3010,   2544,   6969,   7559,
+     1996,   -553,   -395,  -2964,  -3487,   -243,   -467,  -1280,
+    -1082,  -1388,  -1174,  -3215,   -366,   -310,   -849,   -921,
+    -5209,  -1867,   8713,  10351,   1549,  -1656,   -212,  -4634,
+    -6540,   -146,   -593,   2770,    993,   3291,   1180,  -5505,
+      492,    176,   -824,   -979,  -4314,   8513,    913,   7547,
+    -2723,  -1135,  -4423,    -50,  -3476,   -452,   2241,    240,
+     -474,   1987,  -3921,   -420,   -717,   1415,    151,   1254,
+    12929,  -1219,   2448,   1757,   6303, -10204,    -90,   -365,
+     -188,  -2425,    962,  -1932,    182,  -1386,    130,   -262,
+    -4974,    469,   -941,   -676,   6465,   4132,   3167,   3160,
+     5697,  -2551,  -1042,   -612,   -609,  -1981,  -1630,  -1249,
+     -798,  -1247,   -797,   -611,  -2248,  -1437,  -1101,  -1099,
+    -3636,   4859,  18914,  -1335,    810,   -807,  -1441, -21836,
+     -108,    -40,   1078,   4198,  -5609,   -296,    396,   1541,
+      179,   -240,   -936,     66,   8844,   7864,    654,  -4063,
+    -5680,  -4774,  -3774,    -26,  -1007,  -1969,  -4245,   -353,
+     -314,   2193,   1950,    162,   3066,   2726,    226,  -1408,
+     1859,   2634,   9228,    996,   9464,   -211,   -423,  -5197,
+      -60,  -5467,   -299,  -1047,  -1483,   -113,   -160,   -561,
+    -1074,  -1521,  -5330,   -575,   2949,  12260,  10290,   -497,
+    -3943,   -530,  -9174,  -6463,    -15,   -949,  -2206,  -1852,
+    -7700,     89,    372,    312,    709,   2950,   2476,   -119,
+    -2903,   1552,  14867,   9970,   -496,   -514,   -147, -13491,
+    -6068,    -15,    275,   2634,  -1408,   1766,   -944,  -9047,
+      -87,     47,    450,    302,   3243,   8234,   7586,   3373,
+     2151,   -642,  -4138,  -3512,   -694,   -282,  -1630,  -1501,
+    -3812,   -667,  -1695,  -1561,   -425,  -1081,   -996,   -442,
+    -9631,     60,   3501,   5359,  10150,  -5662,      0,   -748,
+    -1752,  -6288,     35,   2058,    -12,   3150,    -19,  -1145,
+     5967,    -37,  -2169,  -3320,  -6874,  -2553,  -5446,  -2195,
+    -7841,  -2884,   -397,  -1810,   -294,  -3753,  -1071,  -2285,
+     -848,   -921,   -342,   -729,  -3290,  -1221,  -2606,  -1050,
+    -3413,  -1141,   4630,  13612,   7897,   -711,    -79,  -1308,
+   -11310,  -3806,   -237,    964,    322,   2836,    948,  -3847,
+     1645,    550,  -2231,  -6561,   4410,  -5678,   8006,  -3992,
+     3811,  -1187,  -1968,  -3912,   -973,   -886,   1528,  -2155,
+     2775,   1074,  -1383,   1951,  -1025,   1321,  -1862,    928,
+     5659,  11535,   2203,   -452,   7169,  -1954,  -8121,   -296,
+      -12,  -3137,  -3984,   -761,  -1551,    156,    318,     60,
+    -2476,  -5048,   -964,    197,   2914,  -2914,   3485,  -3965,
+    13675,   -518,   -518,   -741,   -959, -11414,    518,   -620,
+      620,    705,   -705,    843,  -2433,   2432,  -2909,   3310,
+     7843,   1907,   1022,   8882,   7972,  -3755,   -222,    -63,
+    -4815,  -3879,   -913,   -489,   -119,  -4252,  -1034,   -554,
+    -3816,   -928,   -497,  -4322,  13807,   9531,   1436,   1612,
+     1779, -11636,  -5544,   -125,   -158,   -193,  -8032,  -1210,
+     -835,  -1358,   -938,   -141,  -1499,  -1035,   -156,   -175,
+    13620,  -5337,   5450,  -2263,   1723, -11322,  -1738,  -1813,
+     -312,   -181,   4436,  -4531,   1775,   1881,   -737,    752,
+    -1432,    561,   -573,    238,   5297,   8374,   8872,   7694,
+     6538,  -1712,  -4280,  -4804,  -3613,  -2609,  -2707,  -2868,
+    -4534,  -2487,  -3932,  -4166,  -2113,  -3341,  -3540,  -3070
+};
+
+/* 0.65^i (Zero part) and 0.75^i (Pole part) scaled by 2^15 */
+static const int16_t postfilter_tbl[2][LPC_ORDER] = {
+    /* Zero */
+    { 21299, 13844,  8999,  5849, 3802, 2471, 1606, 1044,  679,  441 },
+    /* Pole */
+    { 24576, 18432, 13824, 10368, 7776, 5832, 4374, 3281, 2460, 1845 }
+};
+
+#endif /* AVCODEC_G723_1_DATA_H */
diff --git a/libavformat/Makefile b/libavformat/Makefile
index af3ebac..43e4224 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -101,6 +101,7 @@ OBJS-$(CONFIG_GXF_DEMUXER)               += gxf.o
 OBJS-$(CONFIG_GXF_MUXER)                 += gxfenc.o audiointerleave.o
 OBJS-$(CONFIG_G722_DEMUXER)              += rawdec.o
 OBJS-$(CONFIG_G722_MUXER)                += rawenc.o
+OBJS-$(CONFIG_G723_1_DEMUXER)            += g723_1.o
 OBJS-$(CONFIG_H261_DEMUXER)              += h261dec.o rawdec.o
 OBJS-$(CONFIG_H261_MUXER)                += rawenc.o
 OBJS-$(CONFIG_H263_DEMUXER)              += h263dec.o rawdec.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 46b3bc7..34e9d61 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -99,6 +99,7 @@ void av_register_all(void)
     REGISTER_MUXER    (FRAMECRC, framecrc);
     REGISTER_MUXER    (FRAMEMD5, framemd5);
     REGISTER_MUXDEMUX (G722, g722);
+    REGISTER_DEMUXER  (G723_1, g723_1);
     REGISTER_MUXER    (GIF, gif);
     REGISTER_DEMUXER  (GSM, gsm);
     REGISTER_MUXDEMUX (GXF, gxf);
diff --git a/libavformat/g723_1.c b/libavformat/g723_1.c
new file mode 100644
index 0000000..415d01b
--- /dev/null
+++ b/libavformat/g723_1.c
@@ -0,0 +1,85 @@
+/*
+ * G.723.1 demuxer
+ * Copyright (c) 2010 Mohamed Naufal Basheer
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * G.723.1 demuxer
+ */
+
+#include "libavutil/audioconvert.h"
+#include "avformat.h"
+#include "internal.h"
+
+static const uint8_t frame_size[4] = { 24, 20, 4, 1 };
+
+static int g723_1_init(AVFormatContext *s)
+{
+    AVStream *st;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type     = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id       = CODEC_ID_G723_1;
+    st->codec->channel_layout = AV_CH_LAYOUT_MONO;
+    st->codec->channels       = 1;
+    st->codec->sample_rate    = 8000;
+
+    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+    st->start_time = 0;
+
+    return 0;
+}
+
+static int g723_1_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    int size, byte, ret;
+
+    pkt->pos = avio_tell(s->pb);
+    byte     = avio_r8(s->pb);
+    size     = frame_size[byte & 3];
+
+    ret = av_new_packet(pkt, size);
+    if (ret < 0)
+        return ret;
+
+    pkt->data[0]      = byte;
+    pkt->duration     = 240;
+    pkt->stream_index = 0;
+
+    ret = avio_read(s->pb, pkt->data + 1, size - 1);
+    if (ret < size - 1) {
+        av_free_packet(pkt);
+        return ret < 0 ? ret : AVERROR_EOF;
+    }
+
+    return pkt->size;
+}
+
+AVInputFormat ff_g723_1_demuxer = {
+    .name        = "g723_1",
+    .long_name   = NULL_IF_CONFIG_SMALL("G.723.1 format"),
+    .read_header = g723_1_init,
+    .read_packet = g723_1_read_packet,
+    .extensions  = "tco",
+    .flags       = AVFMT_GENERIC_INDEX
+};
diff --git a/libavformat/rtp.c b/libavformat/rtp.c
index 6516779..efc84ab 100644
--- a/libavformat/rtp.c
+++ b/libavformat/rtp.c
@@ -44,7 +44,7 @@ static const struct
 {
   {0, "PCMU",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_PCM_MULAW, 8000, 1},
   {3, "GSM",         AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
-  {4, "G723",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
+  {4, "G723",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_G723_1, 8000, 1},
   {5, "DVI4",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},
   {6, "DVI4",        AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 16000, 1},
   {7, "LPC",         AVMEDIA_TYPE_AUDIO,   CODEC_ID_NONE, 8000, 1},



More information about the ffmpeg-cvslog mailing list