/*
 * QCELP decoder
 * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg 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.
 *
 * FFmpeg 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 FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * QCELP decoder
 * @author Reynaldo H. Verdejo Pinochet
 * @remark FFmpeg merging spearheaded by Kenan Gillet
 * @remark Development mentored by Benjamin Larson
 */

#include <stddef.h>

#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/float_dsp.h"
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
#include "qcelpdata.h"
#include "celp_filters.h"
#include "acelp_filters.h"
#include "acelp_vectors.h"
#include "lsp.h"

typedef enum {
    I_F_Q = -1,    /**< insufficient frame quality */
    SILENCE,
    RATE_OCTAVE,
    RATE_QUARTER,
    RATE_HALF,
    RATE_FULL
} qcelp_packet_rate;

typedef struct QCELPContext {
    GetBitContext     gb;
    qcelp_packet_rate bitrate;
    QCELPFrame        frame;    /**< unpacked data frame */

    uint8_t  erasure_count;
    uint8_t  octave_count;      /**< count the consecutive RATE_OCTAVE frames */
    float    prev_lspf[10];
    float    predictor_lspf[10];/**< LSP predictor for RATE_OCTAVE and I_F_Q */
    float    pitch_synthesis_filter_mem[303];
    float    pitch_pre_filter_mem[303];
    float    rnd_fir_filter_mem[180];
    float    formant_mem[170];
    float    last_codebook_gain;
    int      prev_g1[2];
    int      prev_bitrate;
    float    pitch_gain[4];
    uint8_t  pitch_lag[4];
    uint16_t first16bits;
    uint8_t  warned_buf_mismatch_bitrate;

    /* postfilter */
    float    postfilter_synth_mem[10];
    float    postfilter_agc_mem;
    float    postfilter_tilt_mem;
} QCELPContext;

/**
 * Initialize the speech codec according to the specification.
 *
 * TIA/EIA/IS-733 2.4.9
 */
static av_cold int qcelp_decode_init(AVCodecContext *avctx)
{
    QCELPContext *q = avctx->priv_data;
    int i;

    avctx->channels       = 1;
    avctx->channel_layout = AV_CH_LAYOUT_MONO;
    avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;

    for (i = 0; i < 10; i++)
        q->prev_lspf[i] = (i + 1) / 11.0;

    return 0;
}

/**
 * Decode the 10 quantized LSP frequencies from the LSPV/LSP
 * transmission codes of any bitrate and check for badly received packets.
 *
 * @param q the context
 * @param lspf line spectral pair frequencies
 *
 * @return 0 on success, -1 if the packet is badly received
 *
 * TIA/EIA/IS-733 2.4.3.2.6.2-2, 2.4.8.7.3
 */
static int decode_lspf(QCELPContext *q, float *lspf)
{
    int i;
    float tmp_lspf, smooth, erasure_coeff;
    const float *predictors;

    if (q->bitrate == RATE_OCTAVE || q->bitrate == I_F_Q) {
        predictors = q->prev_bitrate != RATE_OCTAVE &&
                     q->prev_bitrate != I_F_Q ? q->prev_lspf
                                              : q->predictor_lspf;

        if (q->bitrate == RATE_OCTAVE) {
            q->octave_count++;

            for (i = 0; i < 10; i++) {
                q->predictor_lspf[i] =
                             lspf[i] = (q->frame.lspv[i] ?  QCELP_LSP_SPREAD_FACTOR
                                                         : -QCELP_LSP_SPREAD_FACTOR) +
                                        predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR   +
                                        (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR) / 11);
            }
            smooth = q->octave_count < 10 ? .875 : 0.1;
        } else {
            erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR;

            av_assert2(q->bitrate == I_F_Q);

            if (q->erasure_count > 1)
                erasure_coeff *= q->erasure_count < 4 ? 0.9 : 0.7;

            for (i = 0; i < 10; i++) {
                q->predictor_lspf[i] =
                             lspf[i] = (i + 1) * (1 - erasure_coeff) / 11 +
                                       erasure_coeff * predictors[i];
            }
            smooth = 0.125;
        }

        // Check the stability of the LSP frequencies.
        lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR);
        for (i = 1; i < 10; i++)
            lspf[i] = FFMAX(lspf[i], lspf[i - 1] + QCELP_LSP_SPREAD_FACTOR);

        lspf[9] = FFMIN(lspf[9], 1.0 - QCELP_LSP_SPREAD_FACTOR);
        for (i = 9; i > 0; i--)
            lspf[i - 1] = FFMIN(lspf[i - 1], lspf[i] - QCELP_LSP_SPREAD_FACTOR);

        // Low-pass filter the LSP frequencies.
        ff_weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0 - smooth, 10);
    } else {
        q->octave_count = 0;

        tmp_lspf = 0.0;
        for (i = 0; i < 5; i++) {
            lspf[2 * i + 0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001;
            lspf[2 * i + 1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001;
        }

        // Check for badly received packets.
        if (q->bitrate == RATE_QUARTER) {
            if (lspf[9] <= .70 || lspf[9] >= .97)
                return -1;
            for (i = 3; i < 10; i++)
                if (fabs(lspf[i] - lspf[i - 2]) < .08)
                    return -1;
        } else {
            if (lspf[9] <= .66 || lspf[9] >= .985)
                return -1;
            for (i = 4; i < 10; i++)
                if (fabs(lspf[i] - lspf[i - 4]) < .0931)
                    return -1;
        }
    }
    return 0;
}

/**
 * Convert codebook transmission codes to GAIN and INDEX.
 *
 * @param q the context
 * @param gain array holding the decoded gain
 *
 * TIA/EIA/IS-733 2.4.6.2
 */
static void decode_gain_and_index(QCELPContext *q, float *gain)
{
    int i, subframes_count, g1[16];
    float slope;

    if (q->bitrate >= RATE_QUARTER) {
        switch (q->bitrate) {
        case RATE_FULL: subframes_count = 16; break;
        case RATE_HALF: subframes_count =  4; break;
        default:        subframes_count =  5;
        }
        for (i = 0; i < subframes_count; i++) {
            g1[i] = 4 * q->frame.cbgain[i];
            if (q->bitrate == RATE_FULL && !((i + 1) & 3)) {
                g1[i] += av_clip((g1[i - 1] + g1[i - 2] + g1[i - 3]) / 3 - 6, 0, 32);
            }

            gain[i] = qcelp_g12ga[g1[i]];

            if (q->frame.cbsign[i]) {
                gain[i] = -gain[i];
                q->frame.cindex[i] = (q->frame.cindex[i] - 89) & 127;
            }
        }

        q->prev_g1[0]         = g1[i - 2];
        q->prev_g1[1]         = g1[i - 1];
        q->last_codebook_gain = qcelp_g12ga[g1[i - 1]];

        if (q->bitrate == RATE_QUARTER) {
            // Provide smoothing of the unvoiced excitation energy.
            gain[7] =       gain[4];
            gain[6] = 0.4 * gain[3] + 0.6 * gain[4];
            gain[5] =       gain[3];
            gain[4] = 0.8 * gain[2] + 0.2 * gain[3];
            gain[3] = 0.2 * gain[1] + 0.8 * gain[2];
            gain[2] =       gain[1];
            gain[1] = 0.6 * gain[0] + 0.4 * gain[1];
        }
    } else if (q->bitrate != SILENCE) {
        if (q->bitrate == RATE_OCTAVE) {
            g1[0] = 2 * q->frame.cbgain[0] +
                    av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54);
            subframes_count = 8;
        } else {
            av_assert2(q->bitrate == I_F_Q);

            g1[0] = q->prev_g1[1];
            switch (q->erasure_count) {
            case 1 : break;
            case 2 : g1[0] -= 1; break;
            case 3 : g1[0] -= 2; break;
            default: g1[0] -= 6;
            }
            if (g1[0] < 0)
                g1[0] = 0;
            subframes_count = 4;
        }
        // This interpolation is done to produce smoother background noise.
        slope = 0.5 * (qcelp_g12ga[g1[0]] - q->last_codebook_gain) / subframes_count;
        for (i = 1; i <= subframes_count; i++)
                gain[i - 1] = q->last_codebook_gain + slope * i;

        q->last_codebook_gain = gain[i - 2];
        q->prev_g1[0]         = q->prev_g1[1];
        q->prev_g1[1]         = g1[0];
    }
}

/**
 * If the received packet is Rate 1/4 a further sanity check is made of the
 * codebook gain.
 *
 * @param cbgain the unpacked cbgain array
 * @return -1 if the sanity check fails, 0 otherwise
 *
 * TIA/EIA/IS-733 2.4.8.7.3
 */
static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain)
{
    int i, diff, prev_diff = 0;

    for (i = 1; i < 5; i++) {
        diff = cbgain[i] - cbgain[i-1];
        if (FFABS(diff) > 10)
            return -1;
        else if (FFABS(diff - prev_diff) > 12)
            return -1;
        prev_diff = diff;
    }
    return 0;
}

/**
 * Compute the scaled codebook vector Cdn From INDEX and GAIN
 * for all rates.
 *
 * The specification lacks some information here.
 *
 * TIA/EIA/IS-733 has an omission on the codebook index determination
 * formula for RATE_FULL and RATE_HALF frames at section 2.4.8.1.1. It says
 * you have to subtract the decoded index parameter from the given scaled
 * codebook vector index 'n' to get the desired circular codebook index, but
 * it does not mention that you have to clamp 'n' to [0-9] in order to get
 * RI-compliant results.
 *
 * The reason for this mistake seems to be the fact they forgot to mention you
 * have to do these calculations per codebook subframe and adjust given
 * equation values accordingly.
 *
 * @param q the context
 * @param gain array holding the 4 pitch subframe gain values
 * @param cdn_vector array for the generated scaled codebook vector
 */
static void compute_svector(QCELPContext *q, const float *gain,
                            float *cdn_vector)
{
    int i, j, k;
    uint16_t cbseed, cindex;
    float *rnd, tmp_gain, fir_filter_value;

    switch (q->bitrate) {
    case RATE_FULL:
        for (i = 0; i < 16; i++) {
            tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
            cindex   = -q->frame.cindex[i];
            for (j = 0; j < 10; j++)
                *cdn_vector++ = tmp_gain *
                                qcelp_rate_full_codebook[cindex++ & 127];
        }
        break;
    case RATE_HALF:
        for (i = 0; i < 4; i++) {
            tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO;
            cindex   = -q->frame.cindex[i];
            for (j = 0; j < 40; j++)
                *cdn_vector++ = tmp_gain *
                                qcelp_rate_half_codebook[cindex++ & 127];
        }
        break;
    case RATE_QUARTER:
        cbseed = (0x0003 & q->frame.lspv[4]) << 14 |
                 (0x003F & q->frame.lspv[3]) <<  8 |
                 (0x0060 & q->frame.lspv[2]) <<  1 |
                 (0x0007 & q->frame.lspv[1]) <<  3 |
                 (0x0038 & q->frame.lspv[0]) >>  3;
        rnd    = q->rnd_fir_filter_mem + 20;
        for (i = 0; i < 8; i++) {
            tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
            for (k = 0; k < 20; k++) {
                cbseed = 521 * cbseed + 259;
                *rnd   = (int16_t) cbseed;

                    // FIR filter
                fir_filter_value = 0.0;
                for (j = 0; j < 10; j++)
                    fir_filter_value += qcelp_rnd_fir_coefs[j] *
                                        (rnd[-j] + rnd[-20+j]);

                fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10];
                *cdn_vector++     = tmp_gain * fir_filter_value;
                rnd++;
            }
        }
        memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160,
               20 * sizeof(float));
        break;
    case RATE_OCTAVE:
        cbseed = q->first16bits;
        for (i = 0; i < 8; i++) {
            tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
            for (j = 0; j < 20; j++) {
                cbseed        = 521 * cbseed + 259;
                *cdn_vector++ = tmp_gain * (int16_t) cbseed;
            }
        }
        break;
    case I_F_Q:
        cbseed = -44; // random codebook index
        for (i = 0; i < 4; i++) {
            tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
            for (j = 0; j < 40; j++)
                *cdn_vector++ = tmp_gain *
                                qcelp_rate_full_codebook[cbseed++ & 127];
        }
        break;
    case SILENCE:
        memset(cdn_vector, 0, 160 * sizeof(float));
        break;
    }
}

/**
 * Apply generic gain control.
 *
 * @param v_out output vector
 * @param v_in gain-controlled vector
 * @param v_ref vector to control gain of
 *
 * TIA/EIA/IS-733 2.4.8.3, 2.4.8.6
 */
static void apply_gain_ctrl(float *v_out, const float *v_ref, const float *v_in)
{
    int i;

    for (i = 0; i < 160; i += 40) {
        float res = avpriv_scalarproduct_float_c(v_ref + i, v_ref + i, 40);
        ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i, res, 40);
    }
}

/**
 * Apply filter in pitch-subframe steps.
 *
 * @param memory buffer for the previous state of the filter
 *        - must be able to contain 303 elements
 *        - the 143 first elements are from the previous state
 *        - the next 160 are for output
 * @param v_in input filter vector
 * @param gain per-subframe gain array, each element is between 0.0 and 2.0
 * @param lag per-subframe lag array, each element is
 *        - between 16 and 143 if its corresponding pfrac is 0,
 *        - between 16 and 139 otherwise
 * @param pfrac per-subframe boolean array, 1 if the lag is fractional, 0
 *        otherwise
 *
 * @return filter output vector
 */
static const float *do_pitchfilter(float memory[303], const float v_in[160],
                                   const float gain[4], const uint8_t *lag,
                                   const uint8_t pfrac[4])
{
    int i, j;
    float *v_lag, *v_out;
    const float *v_len;

    v_out = memory + 143; // Output vector starts at memory[143].

    for (i = 0; i < 4; i++) {
        if (gain[i]) {
            v_lag = memory + 143 + 40 * i - lag[i];
            for (v_len = v_in + 40; v_in < v_len; v_in++) {
                if (pfrac[i]) { // If it is a fractional lag...
                    for (j = 0, *v_out = 0.0; j < 4; j++)
                        *v_out += qcelp_hammsinc_table[j] *
                                  (v_lag[j - 4] + v_lag[3 - j]);
                } else
                    *v_out = *v_lag;

                *v_out = *v_in + gain[i] * *v_out;

                v_lag++;
                v_out++;
            }
        } else {
            memcpy(v_out, v_in, 40 * sizeof(float));
            v_in  += 40;
            v_out += 40;
        }
    }

    memmove(memory, memory + 160, 143 * sizeof(float));
    return memory + 143;
}

/**
 * Apply pitch synthesis filter and pitch prefilter to the scaled codebook vector.
 * TIA/EIA/IS-733 2.4.5.2, 2.4.8.7.2
 *
 * @param q the context
 * @param cdn_vector the scaled codebook vector
 */
static void apply_pitch_filters(QCELPContext *q, float *cdn_vector)
{
    int i;
    const float *v_synthesis_filtered, *v_pre_filtered;

    if (q->bitrate >= RATE_HALF || q->bitrate == SILENCE ||
        (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF))) {

        if (q->bitrate >= RATE_HALF) {
            // Compute gain & lag for the whole frame.
            for (i = 0; i < 4; i++) {
                q->pitch_gain[i] = q->frame.plag[i] ? (q->frame.pgain[i] + 1) * 0.25 : 0.0;

                q->pitch_lag[i] = q->frame.plag[i] + 16;
            }
        } else {
            float max_pitch_gain;

            if (q->bitrate == I_F_Q) {
                  if (q->erasure_count < 3)
                      max_pitch_gain = 0.9 - 0.3 * (q->erasure_count - 1);
                  else
                      max_pitch_gain = 0.0;
            } else {
                av_assert2(q->bitrate == SILENCE);
                max_pitch_gain = 1.0;
            }
            for (i = 0; i < 4; i++)
                q->pitch_gain[i] = FFMIN(q->pitch_gain[i], max_pitch_gain);

            memset(q->frame.pfrac, 0, sizeof(q->frame.pfrac));
        }

        // pitch synthesis filter
        v_synthesis_filtered = do_pitchfilter(q->pitch_synthesis_filter_mem,
                                              cdn_vector, q->pitch_gain,
                                              q->pitch_lag, q->frame.pfrac);

        // pitch prefilter update
        for (i = 0; i < 4; i++)
            q->pitch_gain[i] = 0.5 * FFMIN(q->pitch_gain[i], 1.0);

        v_pre_filtered       = do_pitchfilter(q->pitch_pre_filter_mem,
                                              v_synthesis_filtered,
                                              q->pitch_gain, q->pitch_lag,
                                              q->frame.pfrac);

        apply_gain_ctrl(cdn_vector, v_synthesis_filtered, v_pre_filtered);
    } else {
        memcpy(q->pitch_synthesis_filter_mem,
               cdn_vector + 17, 143 * sizeof(float));
        memcpy(q->pitch_pre_filter_mem, cdn_vector + 17, 143 * sizeof(float));
        memset(q->pitch_gain, 0, sizeof(q->pitch_gain));
        memset(q->pitch_lag,  0, sizeof(q->pitch_lag));
    }
}

/**
 * Reconstruct LPC coefficients from the line spectral pair frequencies
 * and perform bandwidth expansion.
 *
 * @param lspf line spectral pair frequencies
 * @param lpc linear predictive coding coefficients
 *
 * @note: bandwidth_expansion_coeff could be precalculated into a table
 *        but it seems to be slower on x86
 *
 * TIA/EIA/IS-733 2.4.3.3.5
 */
static void lspf2lpc(const float *lspf, float *lpc)
{
    double lsp[10];
    double bandwidth_expansion_coeff = QCELP_BANDWIDTH_EXPANSION_COEFF;
    int i;

    for (i = 0; i < 10; i++)
        lsp[i] = cos(M_PI * lspf[i]);

    ff_acelp_lspd2lpc(lsp, lpc, 5);

    for (i = 0; i < 10; i++) {
        lpc[i]                    *= bandwidth_expansion_coeff;
        bandwidth_expansion_coeff *= QCELP_BANDWIDTH_EXPANSION_COEFF;
    }
}

/**
 * Interpolate LSP frequencies and compute LPC coefficients
 * for a given bitrate & pitch subframe.
 *
 * TIA/EIA/IS-733 2.4.3.3.4, 2.4.8.7.2
 *
 * @param q the context
 * @param curr_lspf LSP frequencies vector of the current frame
 * @param lpc float vector for the resulting LPC
 * @param subframe_num frame number in decoded stream
 */
static void interpolate_lpc(QCELPContext *q, const float *curr_lspf,
                            float *lpc, const int subframe_num)
{
    float interpolated_lspf[10];
    float weight;

    if (q->bitrate >= RATE_QUARTER)
        weight = 0.25 * (subframe_num + 1);
    else if (q->bitrate == RATE_OCTAVE && !subframe_num)
        weight = 0.625;
    else
        weight = 1.0;

    if (weight != 1.0) {
        ff_weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf,
                                weight, 1.0 - weight, 10);
        lspf2lpc(interpolated_lspf, lpc);
    } else if (q->bitrate >= RATE_QUARTER ||
               (q->bitrate == I_F_Q && !subframe_num))
        lspf2lpc(curr_lspf, lpc);
    else if (q->bitrate == SILENCE && !subframe_num)
        lspf2lpc(q->prev_lspf, lpc);
}

static qcelp_packet_rate buf_size2bitrate(const int buf_size)
{
    switch (buf_size) {
    case 35: return RATE_FULL;
    case 17: return RATE_HALF;
    case  8: return RATE_QUARTER;
    case  4: return RATE_OCTAVE;
    case  1: return SILENCE;
    }

    return I_F_Q;
}

/**
 * Determine the bitrate from the frame size and/or the first byte of the frame.
 *
 * @param avctx the AV codec context
 * @param buf_size length of the buffer
 * @param buf the buffer
 *
 * @return the bitrate on success,
 *         I_F_Q  if the bitrate cannot be satisfactorily determined
 *
 * TIA/EIA/IS-733 2.4.8.7.1
 */
static qcelp_packet_rate determine_bitrate(AVCodecContext *avctx,
                                           const int buf_size,
                                           const uint8_t **buf)
{
    qcelp_packet_rate bitrate;

    if ((bitrate = buf_size2bitrate(buf_size)) >= 0) {
        if (bitrate > **buf) {
            QCELPContext *q = avctx->priv_data;
            if (!q->warned_buf_mismatch_bitrate) {
            av_log(avctx, AV_LOG_WARNING,
                   "Claimed bitrate and buffer size mismatch.\n");
                q->warned_buf_mismatch_bitrate = 1;
            }
            bitrate = **buf;
        } else if (bitrate < **buf) {
            av_log(avctx, AV_LOG_ERROR,
                   "Buffer is too small for the claimed bitrate.\n");
            return I_F_Q;
        }
        (*buf)++;
    } else if ((bitrate = buf_size2bitrate(buf_size + 1)) >= 0) {
        av_log(avctx, AV_LOG_WARNING,
               "Bitrate byte missing, guessing bitrate from packet size.\n");
    } else
        return I_F_Q;

    if (bitrate == SILENCE) {
        // FIXME: Remove this warning when tested with samples.
        avpriv_request_sample(avctx, "Blank frame handling");
    }
    return bitrate;
}

static void warn_insufficient_frame_quality(AVCodecContext *avctx,
                                            const char *message)
{
    av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n",
           avctx->frame_number, message);
}

static void postfilter(QCELPContext *q, float *samples, float *lpc)
{
    static const float pow_0_775[10] = {
        0.775000, 0.600625, 0.465484, 0.360750, 0.279582,
        0.216676, 0.167924, 0.130141, 0.100859, 0.078166
    }, pow_0_625[10] = {
        0.625000, 0.390625, 0.244141, 0.152588, 0.095367,
        0.059605, 0.037253, 0.023283, 0.014552, 0.009095
    };
    float lpc_s[10], lpc_p[10], pole_out[170], zero_out[160];
    int n;

    for (n = 0; n < 10; n++) {
        lpc_s[n] = lpc[n] * pow_0_625[n];
        lpc_p[n] = lpc[n] * pow_0_775[n];
    }

    ff_celp_lp_zero_synthesis_filterf(zero_out, lpc_s,
                                      q->formant_mem + 10, 160, 10);
    memcpy(pole_out, q->postfilter_synth_mem, sizeof(float) * 10);
    ff_celp_lp_synthesis_filterf(pole_out + 10, lpc_p, zero_out, 160, 10);
    memcpy(q->postfilter_synth_mem, pole_out + 160, sizeof(float) * 10);

    ff_tilt_compensation(&q->postfilter_tilt_mem, 0.3, pole_out + 10, 160);

    ff_adaptive_gain_control(samples, pole_out + 10,
                             avpriv_scalarproduct_float_c(q->formant_mem + 10,
                                                          q->formant_mem + 10,
                                                          160),
                             160, 0.9375, &q->postfilter_agc_mem);
}

static int qcelp_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
    QCELPContext *q    = avctx->priv_data;
    AVFrame *frame     = data;
    float *outbuffer;
    int   i, ret;
    float quantized_lspf[10], lpc[10];
    float gain[16];
    float *formant_mem;

    /* get output buffer */
    frame->nb_samples = 160;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;
    outbuffer = (float *)frame->data[0];

    if ((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) {
        warn_insufficient_frame_quality(avctx, "Bitrate cannot be determined.");
        goto erasure;
    }

    if (q->bitrate == RATE_OCTAVE &&
        (q->first16bits = AV_RB16(buf)) == 0xFFFF) {
        warn_insufficient_frame_quality(avctx, "Bitrate is 1/8 and first 16 bits are on.");
        goto erasure;
    }

    if (q->bitrate > SILENCE) {
        const QCELPBitmap *bitmaps     = qcelp_unpacking_bitmaps_per_rate[q->bitrate];
        const QCELPBitmap *bitmaps_end = qcelp_unpacking_bitmaps_per_rate[q->bitrate] +
                                         qcelp_unpacking_bitmaps_lengths[q->bitrate];
        uint8_t *unpacked_data         = (uint8_t *)&q->frame;

        if ((ret = init_get_bits8(&q->gb, buf, buf_size)) < 0)
            return ret;

        memset(&q->frame, 0, sizeof(QCELPFrame));

        for (; bitmaps < bitmaps_end; bitmaps++)
            unpacked_data[bitmaps->index] |= get_bits(&q->gb, bitmaps->bitlen) << bitmaps->bitpos;

        // Check for erasures/blanks on rates 1, 1/4 and 1/8.
        if (q->frame.reserved) {
            warn_insufficient_frame_quality(avctx, "Wrong data in reserved frame area.");
            goto erasure;
        }
        if (q->bitrate == RATE_QUARTER &&
            codebook_sanity_check_for_rate_quarter(q->frame.cbgain)) {
            warn_insufficient_frame_quality(avctx, "Codebook gain sanity check failed.");
            goto erasure;
        }

        if (q->bitrate >= RATE_HALF) {
            for (i = 0; i < 4; i++) {
                if (q->frame.pfrac[i] && q->frame.plag[i] >= 124) {
                    warn_insufficient_frame_quality(avctx, "Cannot initialize pitch filter.");
                    goto erasure;
                }
            }
        }
    }

    decode_gain_and_index(q, gain);
    compute_svector(q, gain, outbuffer);

    if (decode_lspf(q, quantized_lspf) < 0) {
        warn_insufficient_frame_quality(avctx, "Badly received packets in frame.");
        goto erasure;
    }

    apply_pitch_filters(q, outbuffer);

    if (q->bitrate == I_F_Q) {
erasure:
        q->bitrate = I_F_Q;
        q->erasure_count++;
        decode_gain_and_index(q, gain);
        compute_svector(q, gain, outbuffer);
        decode_lspf(q, quantized_lspf);
        apply_pitch_filters(q, outbuffer);
    } else
        q->erasure_count = 0;

    formant_mem = q->formant_mem + 10;
    for (i = 0; i < 4; i++) {
        interpolate_lpc(q, quantized_lspf, lpc, i);
        ff_celp_lp_synthesis_filterf(formant_mem, lpc,
                                     outbuffer + i * 40, 40, 10);
        formant_mem += 40;
    }

    // postfilter, as per TIA/EIA/IS-733 2.4.8.6
    postfilter(q, outbuffer, lpc);

    memcpy(q->formant_mem, q->formant_mem + 160, 10 * sizeof(float));

    memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf));
    q->prev_bitrate  = q->bitrate;

    *got_frame_ptr = 1;

    return buf_size;
}

AVCodec ff_qcelp_decoder = {
    .name           = "qcelp",
    .long_name      = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"),
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_QCELP,
    .init           = qcelp_decode_init,
    .decode         = qcelp_decode_frame,
    .capabilities   = AV_CODEC_CAP_DR1,
    .priv_data_size = sizeof(QCELPContext),
};
