/*
 * AMR wideband decoder
 * Copyright (c) 2010 Marcelo Galvao Povoa
 *
 * 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
 * AMR wideband decoder
 */

#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
#include "libavutil/lfg.h"

#include "avcodec.h"
#include "lsp.h"
#include "celp_filters.h"
#include "celp_math.h"
#include "acelp_filters.h"
#include "acelp_vectors.h"
#include "acelp_pitch_delay.h"
#include "internal.h"

#define AMR_USE_16BIT_TABLES
#include "amr.h"

#include "amrwbdata.h"
#include "mips/amrwbdec_mips.h"

typedef struct AMRWBContext {
    AMRWBFrame                             frame; ///< AMRWB parameters decoded from bitstream
    enum Mode                        fr_cur_mode; ///< mode index of current frame
    uint8_t                           fr_quality; ///< frame quality index (FQI)
    float                      isf_cur[LP_ORDER]; ///< working ISF vector from current frame
    float                   isf_q_past[LP_ORDER]; ///< quantized ISF vector of the previous frame
    float               isf_past_final[LP_ORDER]; ///< final processed ISF vector of the previous frame
    double                      isp[4][LP_ORDER]; ///< ISP vectors from current frame
    double               isp_sub4_past[LP_ORDER]; ///< ISP vector for the 4th subframe of the previous frame

    float                   lp_coef[4][LP_ORDER]; ///< Linear Prediction Coefficients from ISP vector

    uint8_t                       base_pitch_lag; ///< integer part of pitch lag for the next relative subframe
    uint8_t                        pitch_lag_int; ///< integer part of pitch lag of the previous subframe

    float excitation_buf[AMRWB_P_DELAY_MAX + LP_ORDER + 2 + AMRWB_SFR_SIZE]; ///< current excitation and all necessary excitation history
    float                            *excitation; ///< points to current excitation in excitation_buf[]

    float           pitch_vector[AMRWB_SFR_SIZE]; ///< adaptive codebook (pitch) vector for current subframe
    float           fixed_vector[AMRWB_SFR_SIZE]; ///< algebraic codebook (fixed) vector for current subframe

    float                    prediction_error[4]; ///< quantified prediction errors {20log10(^gamma_gc)} for previous four subframes
    float                          pitch_gain[6]; ///< quantified pitch gains for the current and previous five subframes
    float                          fixed_gain[2]; ///< quantified fixed gains for the current and previous subframes

    float                              tilt_coef; ///< {beta_1} related to the voicing of the previous subframe

    float                 prev_sparse_fixed_gain; ///< previous fixed gain; used by anti-sparseness to determine "onset"
    uint8_t                    prev_ir_filter_nr; ///< previous impulse response filter "impNr": 0 - strong, 1 - medium, 2 - none
    float                           prev_tr_gain; ///< previous initial gain used by noise enhancer for threshold

    float samples_az[LP_ORDER + AMRWB_SFR_SIZE];         ///< low-band samples and memory from synthesis at 12.8kHz
    float samples_up[UPS_MEM_SIZE + AMRWB_SFR_SIZE];     ///< low-band samples and memory processed for upsampling
    float samples_hb[LP_ORDER_16k + AMRWB_SFR_SIZE_16k]; ///< high-band samples and memory from synthesis at 16kHz

    float          hpf_31_mem[2], hpf_400_mem[2]; ///< previous values in the high pass filters
    float                           demph_mem[1]; ///< previous value in the de-emphasis filter
    float               bpf_6_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band band pass filter
    float                 lpf_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band low pass filter

    AVLFG                                   prng; ///< random number generator for white noise excitation
    uint8_t                          first_frame; ///< flag active during decoding of the first frame
    ACELPFContext                     acelpf_ctx; ///< context for filters for ACELP-based codecs
    ACELPVContext                     acelpv_ctx; ///< context for vector operations for ACELP-based codecs
    CELPFContext                       celpf_ctx; ///< context for filters for CELP-based codecs
    CELPMContext                       celpm_ctx; ///< context for fixed point math operations

} AMRWBContext;

static av_cold int amrwb_decode_init(AVCodecContext *avctx)
{
    AMRWBContext *ctx = avctx->priv_data;
    int i;

    if (avctx->channels > 1) {
        avpriv_report_missing_feature(avctx, "multi-channel AMR");
        return AVERROR_PATCHWELCOME;
    }

    avctx->channels       = 1;
    avctx->channel_layout = AV_CH_LAYOUT_MONO;
    if (!avctx->sample_rate)
        avctx->sample_rate = 16000;
    avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;

    av_lfg_init(&ctx->prng, 1);

    ctx->excitation  = &ctx->excitation_buf[AMRWB_P_DELAY_MAX + LP_ORDER + 1];
    ctx->first_frame = 1;

    for (i = 0; i < LP_ORDER; i++)
        ctx->isf_past_final[i] = isf_init[i] * (1.0f / (1 << 15));

    for (i = 0; i < 4; i++)
        ctx->prediction_error[i] = MIN_ENERGY;

    ff_acelp_filter_init(&ctx->acelpf_ctx);
    ff_acelp_vectors_init(&ctx->acelpv_ctx);
    ff_celp_filter_init(&ctx->celpf_ctx);
    ff_celp_math_init(&ctx->celpm_ctx);

    return 0;
}

/**
 * Decode the frame header in the "MIME/storage" format. This format
 * is simpler and does not carry the auxiliary frame information.
 *
 * @param[in] ctx                  The Context
 * @param[in] buf                  Pointer to the input buffer
 *
 * @return The decoded header length in bytes
 */
static int decode_mime_header(AMRWBContext *ctx, const uint8_t *buf)
{
    /* Decode frame header (1st octet) */
    ctx->fr_cur_mode  = buf[0] >> 3 & 0x0F;
    ctx->fr_quality   = (buf[0] & 0x4) == 0x4;

    return 1;
}

/**
 * Decode quantized ISF vectors using 36-bit indexes (6K60 mode only).
 *
 * @param[in]  ind                 Array of 5 indexes
 * @param[out] isf_q               Buffer for isf_q[LP_ORDER]
 *
 */
static void decode_isf_indices_36b(uint16_t *ind, float *isf_q)
{
    int i;

    for (i = 0; i < 9; i++)
        isf_q[i]      = dico1_isf[ind[0]][i]      * (1.0f / (1 << 15));

    for (i = 0; i < 7; i++)
        isf_q[i + 9]  = dico2_isf[ind[1]][i]      * (1.0f / (1 << 15));

    for (i = 0; i < 5; i++)
        isf_q[i]     += dico21_isf_36b[ind[2]][i] * (1.0f / (1 << 15));

    for (i = 0; i < 4; i++)
        isf_q[i + 5] += dico22_isf_36b[ind[3]][i] * (1.0f / (1 << 15));

    for (i = 0; i < 7; i++)
        isf_q[i + 9] += dico23_isf_36b[ind[4]][i] * (1.0f / (1 << 15));
}

/**
 * Decode quantized ISF vectors using 46-bit indexes (except 6K60 mode).
 *
 * @param[in]  ind                 Array of 7 indexes
 * @param[out] isf_q               Buffer for isf_q[LP_ORDER]
 *
 */
static void decode_isf_indices_46b(uint16_t *ind, float *isf_q)
{
    int i;

    for (i = 0; i < 9; i++)
        isf_q[i]       = dico1_isf[ind[0]][i]  * (1.0f / (1 << 15));

    for (i = 0; i < 7; i++)
        isf_q[i + 9]   = dico2_isf[ind[1]][i]  * (1.0f / (1 << 15));

    for (i = 0; i < 3; i++)
        isf_q[i]      += dico21_isf[ind[2]][i] * (1.0f / (1 << 15));

    for (i = 0; i < 3; i++)
        isf_q[i + 3]  += dico22_isf[ind[3]][i] * (1.0f / (1 << 15));

    for (i = 0; i < 3; i++)
        isf_q[i + 6]  += dico23_isf[ind[4]][i] * (1.0f / (1 << 15));

    for (i = 0; i < 3; i++)
        isf_q[i + 9]  += dico24_isf[ind[5]][i] * (1.0f / (1 << 15));

    for (i = 0; i < 4; i++)
        isf_q[i + 12] += dico25_isf[ind[6]][i] * (1.0f / (1 << 15));
}

/**
 * Apply mean and past ISF values using the prediction factor.
 * Updates past ISF vector.
 *
 * @param[in,out] isf_q            Current quantized ISF
 * @param[in,out] isf_past         Past quantized ISF
 *
 */
static void isf_add_mean_and_past(float *isf_q, float *isf_past)
{
    int i;
    float tmp;

    for (i = 0; i < LP_ORDER; i++) {
        tmp = isf_q[i];
        isf_q[i] += isf_mean[i] * (1.0f / (1 << 15));
        isf_q[i] += PRED_FACTOR * isf_past[i];
        isf_past[i] = tmp;
    }
}

/**
 * Interpolate the fourth ISP vector from current and past frames
 * to obtain an ISP vector for each subframe.
 *
 * @param[in,out] isp_q            ISPs for each subframe
 * @param[in]     isp4_past        Past ISP for subframe 4
 */
static void interpolate_isp(double isp_q[4][LP_ORDER], const double *isp4_past)
{
    int i, k;

    for (k = 0; k < 3; k++) {
        float c = isfp_inter[k];
        for (i = 0; i < LP_ORDER; i++)
            isp_q[k][i] = (1.0 - c) * isp4_past[i] + c * isp_q[3][i];
    }
}

/**
 * Decode an adaptive codebook index into pitch lag (except 6k60, 8k85 modes).
 * Calculate integer lag and fractional lag always using 1/4 resolution.
 * In 1st and 3rd subframes the index is relative to last subframe integer lag.
 *
 * @param[out]    lag_int          Decoded integer pitch lag
 * @param[out]    lag_frac         Decoded fractional pitch lag
 * @param[in]     pitch_index      Adaptive codebook pitch index
 * @param[in,out] base_lag_int     Base integer lag used in relative subframes
 * @param[in]     subframe         Current subframe index (0 to 3)
 */
static void decode_pitch_lag_high(int *lag_int, int *lag_frac, int pitch_index,
                                  uint8_t *base_lag_int, int subframe)
{
    if (subframe == 0 || subframe == 2) {
        if (pitch_index < 376) {
            *lag_int  = (pitch_index + 137) >> 2;
            *lag_frac = pitch_index - (*lag_int << 2) + 136;
        } else if (pitch_index < 440) {
            *lag_int  = (pitch_index + 257 - 376) >> 1;
            *lag_frac = (pitch_index - (*lag_int << 1) + 256 - 376) << 1;
            /* the actual resolution is 1/2 but expressed as 1/4 */
        } else {
            *lag_int  = pitch_index - 280;
            *lag_frac = 0;
        }
        /* minimum lag for next subframe */
        *base_lag_int = av_clip(*lag_int - 8 - (*lag_frac < 0),
                                AMRWB_P_DELAY_MIN, AMRWB_P_DELAY_MAX - 15);
        // XXX: the spec states clearly that *base_lag_int should be
        // the nearest integer to *lag_int (minus 8), but the ref code
        // actually always uses its floor, I'm following the latter
    } else {
        *lag_int  = (pitch_index + 1) >> 2;
        *lag_frac = pitch_index - (*lag_int << 2);
        *lag_int += *base_lag_int;
    }
}

/**
 * Decode an adaptive codebook index into pitch lag for 8k85 and 6k60 modes.
 * The description is analogous to decode_pitch_lag_high, but in 6k60 the
 * relative index is used for all subframes except the first.
 */
static void decode_pitch_lag_low(int *lag_int, int *lag_frac, int pitch_index,
                                 uint8_t *base_lag_int, int subframe, enum Mode mode)
{
    if (subframe == 0 || (subframe == 2 && mode != MODE_6k60)) {
        if (pitch_index < 116) {
            *lag_int  = (pitch_index + 69) >> 1;
            *lag_frac = (pitch_index - (*lag_int << 1) + 68) << 1;
        } else {
            *lag_int  = pitch_index - 24;
            *lag_frac = 0;
        }
        // XXX: same problem as before
        *base_lag_int = av_clip(*lag_int - 8 - (*lag_frac < 0),
                                AMRWB_P_DELAY_MIN, AMRWB_P_DELAY_MAX - 15);
    } else {
        *lag_int  = (pitch_index + 1) >> 1;
        *lag_frac = (pitch_index - (*lag_int << 1)) << 1;
        *lag_int += *base_lag_int;
    }
}

/**
 * Find the pitch vector by interpolating the past excitation at the
 * pitch delay, which is obtained in this function.
 *
 * @param[in,out] ctx              The context
 * @param[in]     amr_subframe     Current subframe data
 * @param[in]     subframe         Current subframe index (0 to 3)
 */
static void decode_pitch_vector(AMRWBContext *ctx,
                                const AMRWBSubFrame *amr_subframe,
                                const int subframe)
{
    int pitch_lag_int, pitch_lag_frac;
    int i;
    float *exc     = ctx->excitation;
    enum Mode mode = ctx->fr_cur_mode;

    if (mode <= MODE_8k85) {
        decode_pitch_lag_low(&pitch_lag_int, &pitch_lag_frac, amr_subframe->adap,
                              &ctx->base_pitch_lag, subframe, mode);
    } else
        decode_pitch_lag_high(&pitch_lag_int, &pitch_lag_frac, amr_subframe->adap,
                              &ctx->base_pitch_lag, subframe);

    ctx->pitch_lag_int = pitch_lag_int;
    pitch_lag_int += pitch_lag_frac > 0;

    /* Calculate the pitch vector by interpolating the past excitation at the
       pitch lag using a hamming windowed sinc function */
    ctx->acelpf_ctx.acelp_interpolatef(exc,
                          exc + 1 - pitch_lag_int,
                          ac_inter, 4,
                          pitch_lag_frac + (pitch_lag_frac > 0 ? 0 : 4),
                          LP_ORDER, AMRWB_SFR_SIZE + 1);

    /* Check which pitch signal path should be used
     * 6k60 and 8k85 modes have the ltp flag set to 0 */
    if (amr_subframe->ltp) {
        memcpy(ctx->pitch_vector, exc, AMRWB_SFR_SIZE * sizeof(float));
    } else {
        for (i = 0; i < AMRWB_SFR_SIZE; i++)
            ctx->pitch_vector[i] = 0.18 * exc[i - 1] + 0.64 * exc[i] +
                                   0.18 * exc[i + 1];
        memcpy(exc, ctx->pitch_vector, AMRWB_SFR_SIZE * sizeof(float));
    }
}

/** Get x bits in the index interval [lsb,lsb+len-1] inclusive */
#define BIT_STR(x,lsb,len) av_mod_uintp2((x) >> (lsb), (len))

/** Get the bit at specified position */
#define BIT_POS(x, p) (((x) >> (p)) & 1)

/**
 * The next six functions decode_[i]p_track decode exactly i pulses
 * positions and amplitudes (-1 or 1) in a subframe track using
 * an encoded pulse indexing (TS 26.190 section 5.8.2).
 *
 * The results are given in out[], in which a negative number means
 * amplitude -1 and vice versa (i.e., ampl(x) = x / abs(x) ).
 *
 * @param[out] out                 Output buffer (writes i elements)
 * @param[in]  code                Pulse index (no. of bits varies, see below)
 * @param[in]  m                   (log2) Number of potential positions
 * @param[in]  off                 Offset for decoded positions
 */
static inline void decode_1p_track(int *out, int code, int m, int off)
{
    int pos = BIT_STR(code, 0, m) + off; ///code: m+1 bits

    out[0] = BIT_POS(code, m) ? -pos : pos;
}

static inline void decode_2p_track(int *out, int code, int m, int off) ///code: 2m+1 bits
{
    int pos0 = BIT_STR(code, m, m) + off;
    int pos1 = BIT_STR(code, 0, m) + off;

    out[0] = BIT_POS(code, 2*m) ? -pos0 : pos0;
    out[1] = BIT_POS(code, 2*m) ? -pos1 : pos1;
    out[1] = pos0 > pos1 ? -out[1] : out[1];
}

static void decode_3p_track(int *out, int code, int m, int off) ///code: 3m+1 bits
{
    int half_2p = BIT_POS(code, 2*m - 1) << (m - 1);

    decode_2p_track(out, BIT_STR(code, 0, 2*m - 1),
                    m - 1, off + half_2p);
    decode_1p_track(out + 2, BIT_STR(code, 2*m, m + 1), m, off);
}

static void decode_4p_track(int *out, int code, int m, int off) ///code: 4m bits
{
    int half_4p, subhalf_2p;
    int b_offset = 1 << (m - 1);

    switch (BIT_STR(code, 4*m - 2, 2)) { /* case ID (2 bits) */
    case 0: /* 0 pulses in A, 4 pulses in B or vice versa */
        half_4p = BIT_POS(code, 4*m - 3) << (m - 1); // which has 4 pulses
        subhalf_2p = BIT_POS(code, 2*m - 3) << (m - 2);

        decode_2p_track(out, BIT_STR(code, 0, 2*m - 3),
                        m - 2, off + half_4p + subhalf_2p);
        decode_2p_track(out + 2, BIT_STR(code, 2*m - 2, 2*m - 1),
                        m - 1, off + half_4p);
        break;
    case 1: /* 1 pulse in A, 3 pulses in B */
        decode_1p_track(out, BIT_STR(code,  3*m - 2, m),
                        m - 1, off);
        decode_3p_track(out + 1, BIT_STR(code, 0, 3*m - 2),
                        m - 1, off + b_offset);
        break;
    case 2: /* 2 pulses in each half */
        decode_2p_track(out, BIT_STR(code, 2*m - 1, 2*m - 1),
                        m - 1, off);
        decode_2p_track(out + 2, BIT_STR(code, 0, 2*m - 1),
                        m - 1, off + b_offset);
        break;
    case 3: /* 3 pulses in A, 1 pulse in B */
        decode_3p_track(out, BIT_STR(code, m, 3*m - 2),
                        m - 1, off);
        decode_1p_track(out + 3, BIT_STR(code, 0, m),
                        m - 1, off + b_offset);
        break;
    }
}

static void decode_5p_track(int *out, int code, int m, int off) ///code: 5m bits
{
    int half_3p = BIT_POS(code, 5*m - 1) << (m - 1);

    decode_3p_track(out, BIT_STR(code, 2*m + 1, 3*m - 2),
                    m - 1, off + half_3p);

    decode_2p_track(out + 3, BIT_STR(code, 0, 2*m + 1), m, off);
}

static void decode_6p_track(int *out, int code, int m, int off) ///code: 6m-2 bits
{
    int b_offset = 1 << (m - 1);
    /* which half has more pulses in cases 0 to 2 */
    int half_more  = BIT_POS(code, 6*m - 5) << (m - 1);
    int half_other = b_offset - half_more;

    switch (BIT_STR(code, 6*m - 4, 2)) { /* case ID (2 bits) */
    case 0: /* 0 pulses in A, 6 pulses in B or vice versa */
        decode_1p_track(out, BIT_STR(code, 0, m),
                        m - 1, off + half_more);
        decode_5p_track(out + 1, BIT_STR(code, m, 5*m - 5),
                        m - 1, off + half_more);
        break;
    case 1: /* 1 pulse in A, 5 pulses in B or vice versa */
        decode_1p_track(out, BIT_STR(code, 0, m),
                        m - 1, off + half_other);
        decode_5p_track(out + 1, BIT_STR(code, m, 5*m - 5),
                        m - 1, off + half_more);
        break;
    case 2: /* 2 pulses in A, 4 pulses in B or vice versa */
        decode_2p_track(out, BIT_STR(code, 0, 2*m - 1),
                        m - 1, off + half_other);
        decode_4p_track(out + 2, BIT_STR(code, 2*m - 1, 4*m - 4),
                        m - 1, off + half_more);
        break;
    case 3: /* 3 pulses in A, 3 pulses in B */
        decode_3p_track(out, BIT_STR(code, 3*m - 2, 3*m - 2),
                        m - 1, off);
        decode_3p_track(out + 3, BIT_STR(code, 0, 3*m - 2),
                        m - 1, off + b_offset);
        break;
    }
}

/**
 * Decode the algebraic codebook index to pulse positions and signs,
 * then construct the algebraic codebook vector.
 *
 * @param[out] fixed_vector        Buffer for the fixed codebook excitation
 * @param[in]  pulse_hi            MSBs part of the pulse index array (higher modes only)
 * @param[in]  pulse_lo            LSBs part of the pulse index array
 * @param[in]  mode                Mode of the current frame
 */
static void decode_fixed_vector(float *fixed_vector, const uint16_t *pulse_hi,
                                const uint16_t *pulse_lo, const enum Mode mode)
{
    /* sig_pos stores for each track the decoded pulse position indexes
     * (1-based) multiplied by its corresponding amplitude (+1 or -1) */
    int sig_pos[4][6];
    int spacing = (mode == MODE_6k60) ? 2 : 4;
    int i, j;

    switch (mode) {
    case MODE_6k60:
        for (i = 0; i < 2; i++)
            decode_1p_track(sig_pos[i], pulse_lo[i], 5, 1);
        break;
    case MODE_8k85:
        for (i = 0; i < 4; i++)
            decode_1p_track(sig_pos[i], pulse_lo[i], 4, 1);
        break;
    case MODE_12k65:
        for (i = 0; i < 4; i++)
            decode_2p_track(sig_pos[i], pulse_lo[i], 4, 1);
        break;
    case MODE_14k25:
        for (i = 0; i < 2; i++)
            decode_3p_track(sig_pos[i], pulse_lo[i], 4, 1);
        for (i = 2; i < 4; i++)
            decode_2p_track(sig_pos[i], pulse_lo[i], 4, 1);
        break;
    case MODE_15k85:
        for (i = 0; i < 4; i++)
            decode_3p_track(sig_pos[i], pulse_lo[i], 4, 1);
        break;
    case MODE_18k25:
        for (i = 0; i < 4; i++)
            decode_4p_track(sig_pos[i], (int) pulse_lo[i] +
                           ((int) pulse_hi[i] << 14), 4, 1);
        break;
    case MODE_19k85:
        for (i = 0; i < 2; i++)
            decode_5p_track(sig_pos[i], (int) pulse_lo[i] +
                           ((int) pulse_hi[i] << 10), 4, 1);
        for (i = 2; i < 4; i++)
            decode_4p_track(sig_pos[i], (int) pulse_lo[i] +
                           ((int) pulse_hi[i] << 14), 4, 1);
        break;
    case MODE_23k05:
    case MODE_23k85:
        for (i = 0; i < 4; i++)
            decode_6p_track(sig_pos[i], (int) pulse_lo[i] +
                           ((int) pulse_hi[i] << 11), 4, 1);
        break;
    }

    memset(fixed_vector, 0, sizeof(float) * AMRWB_SFR_SIZE);

    for (i = 0; i < 4; i++)
        for (j = 0; j < pulses_nb_per_mode_tr[mode][i]; j++) {
            int pos = (FFABS(sig_pos[i][j]) - 1) * spacing + i;

            fixed_vector[pos] += sig_pos[i][j] < 0 ? -1.0 : 1.0;
        }
}

/**
 * Decode pitch gain and fixed gain correction factor.
 *
 * @param[in]  vq_gain             Vector-quantized index for gains
 * @param[in]  mode                Mode of the current frame
 * @param[out] fixed_gain_factor   Decoded fixed gain correction factor
 * @param[out] pitch_gain          Decoded pitch gain
 */
static void decode_gains(const uint8_t vq_gain, const enum Mode mode,
                         float *fixed_gain_factor, float *pitch_gain)
{
    const int16_t *gains = (mode <= MODE_8k85 ? qua_gain_6b[vq_gain] :
                                                qua_gain_7b[vq_gain]);

    *pitch_gain        = gains[0] * (1.0f / (1 << 14));
    *fixed_gain_factor = gains[1] * (1.0f / (1 << 11));
}

/**
 * Apply pitch sharpening filters to the fixed codebook vector.
 *
 * @param[in]     ctx              The context
 * @param[in,out] fixed_vector     Fixed codebook excitation
 */
// XXX: Spec states this procedure should be applied when the pitch
// lag is less than 64, but this checking seems absent in reference and AMR-NB
static void pitch_sharpening(AMRWBContext *ctx, float *fixed_vector)
{
    int i;

    /* Tilt part */
    for (i = AMRWB_SFR_SIZE - 1; i != 0; i--)
        fixed_vector[i] -= fixed_vector[i - 1] * ctx->tilt_coef;

    /* Periodicity enhancement part */
    for (i = ctx->pitch_lag_int; i < AMRWB_SFR_SIZE; i++)
        fixed_vector[i] += fixed_vector[i - ctx->pitch_lag_int] * 0.85;
}

/**
 * Calculate the voicing factor (-1.0 = unvoiced to 1.0 = voiced).
 *
 * @param[in] p_vector, f_vector   Pitch and fixed excitation vectors
 * @param[in] p_gain, f_gain       Pitch and fixed gains
 * @param[in] ctx                  The context
 */
// XXX: There is something wrong with the precision here! The magnitudes
// of the energies are not correct. Please check the reference code carefully
static float voice_factor(float *p_vector, float p_gain,
                          float *f_vector, float f_gain,
                          CELPMContext *ctx)
{
    double p_ener = (double) ctx->dot_productf(p_vector, p_vector,
                                                          AMRWB_SFR_SIZE) *
                    p_gain * p_gain;
    double f_ener = (double) ctx->dot_productf(f_vector, f_vector,
                                                          AMRWB_SFR_SIZE) *
                    f_gain * f_gain;

    return (p_ener - f_ener) / (p_ener + f_ener);
}

/**
 * Reduce fixed vector sparseness by smoothing with one of three IR filters,
 * also known as "adaptive phase dispersion".
 *
 * @param[in]     ctx              The context
 * @param[in,out] fixed_vector     Unfiltered fixed vector
 * @param[out]    buf              Space for modified vector if necessary
 *
 * @return The potentially overwritten filtered fixed vector address
 */
static float *anti_sparseness(AMRWBContext *ctx,
                              float *fixed_vector, float *buf)
{
    int ir_filter_nr;

    if (ctx->fr_cur_mode > MODE_8k85) // no filtering in higher modes
        return fixed_vector;

    if (ctx->pitch_gain[0] < 0.6) {
        ir_filter_nr = 0;      // strong filtering
    } else if (ctx->pitch_gain[0] < 0.9) {
        ir_filter_nr = 1;      // medium filtering
    } else
        ir_filter_nr = 2;      // no filtering

    /* detect 'onset' */
    if (ctx->fixed_gain[0] > 3.0 * ctx->fixed_gain[1]) {
        if (ir_filter_nr < 2)
            ir_filter_nr++;
    } else {
        int i, count = 0;

        for (i = 0; i < 6; i++)
            if (ctx->pitch_gain[i] < 0.6)
                count++;

        if (count > 2)
            ir_filter_nr = 0;

        if (ir_filter_nr > ctx->prev_ir_filter_nr + 1)
            ir_filter_nr--;
    }

    /* update ir filter strength history */
    ctx->prev_ir_filter_nr = ir_filter_nr;

    ir_filter_nr += (ctx->fr_cur_mode == MODE_8k85);

    if (ir_filter_nr < 2) {
        int i;
        const float *coef = ir_filters_lookup[ir_filter_nr];

        /* Circular convolution code in the reference
         * decoder was modified to avoid using one
         * extra array. The filtered vector is given by:
         *
         * c2(n) = sum(i,0,len-1){ c(i) * coef( (n - i + len) % len ) }
         */

        memset(buf, 0, sizeof(float) * AMRWB_SFR_SIZE);
        for (i = 0; i < AMRWB_SFR_SIZE; i++)
            if (fixed_vector[i])
                ff_celp_circ_addf(buf, buf, coef, i, fixed_vector[i],
                                  AMRWB_SFR_SIZE);
        fixed_vector = buf;
    }

    return fixed_vector;
}

/**
 * Calculate a stability factor {teta} based on distance between
 * current and past isf. A value of 1 shows maximum signal stability.
 */
static float stability_factor(const float *isf, const float *isf_past)
{
    int i;
    float acc = 0.0;

    for (i = 0; i < LP_ORDER - 1; i++)
        acc += (isf[i] - isf_past[i]) * (isf[i] - isf_past[i]);

    // XXX: This part is not so clear from the reference code
    // the result is more accurate changing the "/ 256" to "* 512"
    return FFMAX(0.0, 1.25 - acc * 0.8 * 512);
}

/**
 * Apply a non-linear fixed gain smoothing in order to reduce
 * fluctuation in the energy of excitation.
 *
 * @param[in]     fixed_gain       Unsmoothed fixed gain
 * @param[in,out] prev_tr_gain     Previous threshold gain (updated)
 * @param[in]     voice_fac        Frame voicing factor
 * @param[in]     stab_fac         Frame stability factor
 *
 * @return The smoothed gain
 */
static float noise_enhancer(float fixed_gain, float *prev_tr_gain,
                            float voice_fac,  float stab_fac)
{
    float sm_fac = 0.5 * (1 - voice_fac) * stab_fac;
    float g0;

    // XXX: the following fixed-point constants used to in(de)crement
    // gain by 1.5dB were taken from the reference code, maybe it could
    // be simpler
    if (fixed_gain < *prev_tr_gain) {
        g0 = FFMIN(*prev_tr_gain, fixed_gain + fixed_gain *
                     (6226 * (1.0f / (1 << 15)))); // +1.5 dB
    } else
        g0 = FFMAX(*prev_tr_gain, fixed_gain *
                    (27536 * (1.0f / (1 << 15)))); // -1.5 dB

    *prev_tr_gain = g0; // update next frame threshold

    return sm_fac * g0 + (1 - sm_fac) * fixed_gain;
}

/**
 * Filter the fixed_vector to emphasize the higher frequencies.
 *
 * @param[in,out] fixed_vector     Fixed codebook vector
 * @param[in]     voice_fac        Frame voicing factor
 */
static void pitch_enhancer(float *fixed_vector, float voice_fac)
{
    int i;
    float cpe  = 0.125 * (1 + voice_fac);
    float last = fixed_vector[0]; // holds c(i - 1)

    fixed_vector[0] -= cpe * fixed_vector[1];

    for (i = 1; i < AMRWB_SFR_SIZE - 1; i++) {
        float cur = fixed_vector[i];

        fixed_vector[i] -= cpe * (last + fixed_vector[i + 1]);
        last = cur;
    }

    fixed_vector[AMRWB_SFR_SIZE - 1] -= cpe * last;
}

/**
 * Conduct 16th order linear predictive coding synthesis from excitation.
 *
 * @param[in]     ctx              Pointer to the AMRWBContext
 * @param[in]     lpc              Pointer to the LPC coefficients
 * @param[out]    excitation       Buffer for synthesis final excitation
 * @param[in]     fixed_gain       Fixed codebook gain for synthesis
 * @param[in]     fixed_vector     Algebraic codebook vector
 * @param[in,out] samples          Pointer to the output samples and memory
 */
static void synthesis(AMRWBContext *ctx, float *lpc, float *excitation,
                      float fixed_gain, const float *fixed_vector,
                      float *samples)
{
    ctx->acelpv_ctx.weighted_vector_sumf(excitation, ctx->pitch_vector, fixed_vector,
                            ctx->pitch_gain[0], fixed_gain, AMRWB_SFR_SIZE);

    /* emphasize pitch vector contribution in low bitrate modes */
    if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) {
        int i;
        float energy = ctx->celpm_ctx.dot_productf(excitation, excitation,
                                                    AMRWB_SFR_SIZE);

        // XXX: Weird part in both ref code and spec. A unknown parameter
        // {beta} seems to be identical to the current pitch gain
        float pitch_factor = 0.25 * ctx->pitch_gain[0] * ctx->pitch_gain[0];

        for (i = 0; i < AMRWB_SFR_SIZE; i++)
            excitation[i] += pitch_factor * ctx->pitch_vector[i];

        ff_scale_vector_to_given_sum_of_squares(excitation, excitation,
                                                energy, AMRWB_SFR_SIZE);
    }

    ctx->celpf_ctx.celp_lp_synthesis_filterf(samples, lpc, excitation,
                                 AMRWB_SFR_SIZE, LP_ORDER);
}

/**
 * Apply to synthesis a de-emphasis filter of the form:
 * H(z) = 1 / (1 - m * z^-1)
 *
 * @param[out]    out              Output buffer
 * @param[in]     in               Input samples array with in[-1]
 * @param[in]     m                Filter coefficient
 * @param[in,out] mem              State from last filtering
 */
static void de_emphasis(float *out, float *in, float m, float mem[1])
{
    int i;

    out[0] = in[0] + m * mem[0];

    for (i = 1; i < AMRWB_SFR_SIZE; i++)
         out[i] = in[i] + out[i - 1] * m;

    mem[0] = out[AMRWB_SFR_SIZE - 1];
}

/**
 * Upsample a signal by 5/4 ratio (from 12.8kHz to 16kHz) using
 * a FIR interpolation filter. Uses past data from before *in address.
 *
 * @param[out] out                 Buffer for interpolated signal
 * @param[in]  in                  Current signal data (length 0.8*o_size)
 * @param[in]  o_size              Output signal length
 * @param[in] ctx                  The context
 */
static void upsample_5_4(float *out, const float *in, int o_size, CELPMContext *ctx)
{
    const float *in0 = in - UPS_FIR_SIZE + 1;
    int i, j, k;
    int int_part = 0, frac_part;

    i = 0;
    for (j = 0; j < o_size / 5; j++) {
        out[i] = in[int_part];
        frac_part = 4;
        i++;

        for (k = 1; k < 5; k++) {
            out[i] = ctx->dot_productf(in0 + int_part,
                                                  upsample_fir[4 - frac_part],
                                                  UPS_MEM_SIZE);
            int_part++;
            frac_part--;
            i++;
        }
    }
}

/**
 * Calculate the high-band gain based on encoded index (23k85 mode) or
 * on the low-band speech signal and the Voice Activity Detection flag.
 *
 * @param[in] ctx                  The context
 * @param[in] synth                LB speech synthesis at 12.8k
 * @param[in] hb_idx               Gain index for mode 23k85 only
 * @param[in] vad                  VAD flag for the frame
 */
static float find_hb_gain(AMRWBContext *ctx, const float *synth,
                          uint16_t hb_idx, uint8_t vad)
{
    int wsp = (vad > 0);
    float tilt;

    if (ctx->fr_cur_mode == MODE_23k85)
        return qua_hb_gain[hb_idx] * (1.0f / (1 << 14));

    tilt = ctx->celpm_ctx.dot_productf(synth, synth + 1, AMRWB_SFR_SIZE - 1) /
           ctx->celpm_ctx.dot_productf(synth, synth, AMRWB_SFR_SIZE);

    /* return gain bounded by [0.1, 1.0] */
    return av_clipf((1.0 - FFMAX(0.0, tilt)) * (1.25 - 0.25 * wsp), 0.1, 1.0);
}

/**
 * Generate the high-band excitation with the same energy from the lower
 * one and scaled by the given gain.
 *
 * @param[in]  ctx                 The context
 * @param[out] hb_exc              Buffer for the excitation
 * @param[in]  synth_exc           Low-band excitation used for synthesis
 * @param[in]  hb_gain             Wanted excitation gain
 */
static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
                                 const float *synth_exc, float hb_gain)
{
    int i;
    float energy = ctx->celpm_ctx.dot_productf(synth_exc, synth_exc,
                                                AMRWB_SFR_SIZE);

    /* Generate a white-noise excitation */
    for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
        hb_exc[i] = 32768.0 - (uint16_t) av_lfg_get(&ctx->prng);

    ff_scale_vector_to_given_sum_of_squares(hb_exc, hb_exc,
                                            energy * hb_gain * hb_gain,
                                            AMRWB_SFR_SIZE_16k);
}

/**
 * Calculate the auto-correlation for the ISF difference vector.
 */
static float auto_correlation(float *diff_isf, float mean, int lag)
{
    int i;
    float sum = 0.0;

    for (i = 7; i < LP_ORDER - 2; i++) {
        float prod = (diff_isf[i] - mean) * (diff_isf[i - lag] - mean);
        sum += prod * prod;
    }
    return sum;
}

/**
 * Extrapolate a ISF vector to the 16kHz range (20th order LP)
 * used at mode 6k60 LP filter for the high frequency band.
 *
 * @param[out] isf Buffer for extrapolated isf; contains LP_ORDER
 *                 values on input
 */
static void extrapolate_isf(float isf[LP_ORDER_16k])
{
    float diff_isf[LP_ORDER - 2], diff_mean;
    float corr_lag[3];
    float est, scale;
    int i, j, i_max_corr;

    isf[LP_ORDER_16k - 1] = isf[LP_ORDER - 1];

    /* Calculate the difference vector */
    for (i = 0; i < LP_ORDER - 2; i++)
        diff_isf[i] = isf[i + 1] - isf[i];

    diff_mean = 0.0;
    for (i = 2; i < LP_ORDER - 2; i++)
        diff_mean += diff_isf[i] * (1.0f / (LP_ORDER - 4));

    /* Find which is the maximum autocorrelation */
    i_max_corr = 0;
    for (i = 0; i < 3; i++) {
        corr_lag[i] = auto_correlation(diff_isf, diff_mean, i + 2);

        if (corr_lag[i] > corr_lag[i_max_corr])
            i_max_corr = i;
    }
    i_max_corr++;

    for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)
        isf[i] = isf[i - 1] + isf[i - 1 - i_max_corr]
                            - isf[i - 2 - i_max_corr];

    /* Calculate an estimate for ISF(18) and scale ISF based on the error */
    est   = 7965 + (isf[2] - isf[3] - isf[4]) / 6.0;
    scale = 0.5 * (FFMIN(est, 7600) - isf[LP_ORDER - 2]) /
            (isf[LP_ORDER_16k - 2] - isf[LP_ORDER - 2]);

    for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++)
        diff_isf[j] = scale * (isf[i] - isf[i - 1]);

    /* Stability insurance */
    for (i = 1; i < LP_ORDER_16k - LP_ORDER; i++)
        if (diff_isf[i] + diff_isf[i - 1] < 5.0) {
            if (diff_isf[i] > diff_isf[i - 1]) {
                diff_isf[i - 1] = 5.0 - diff_isf[i];
            } else
                diff_isf[i] = 5.0 - diff_isf[i - 1];
        }

    for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++)
        isf[i] = isf[i - 1] + diff_isf[j] * (1.0f / (1 << 15));

    /* Scale the ISF vector for 16000 Hz */
    for (i = 0; i < LP_ORDER_16k - 1; i++)
        isf[i] *= 0.8;
}

/**
 * Spectral expand the LP coefficients using the equation:
 *   y[i] = x[i] * (gamma ** i)
 *
 * @param[out] out                 Output buffer (may use input array)
 * @param[in]  lpc                 LP coefficients array
 * @param[in]  gamma               Weighting factor
 * @param[in]  size                LP array size
 */
static void lpc_weighting(float *out, const float *lpc, float gamma, int size)
{
    int i;
    float fac = gamma;

    for (i = 0; i < size; i++) {
        out[i] = lpc[i] * fac;
        fac   *= gamma;
    }
}

/**
 * Conduct 20th order linear predictive coding synthesis for the high
 * frequency band excitation at 16kHz.
 *
 * @param[in]     ctx              The context
 * @param[in]     subframe         Current subframe index (0 to 3)
 * @param[in,out] samples          Pointer to the output speech samples
 * @param[in]     exc              Generated white-noise scaled excitation
 * @param[in]     isf              Current frame isf vector
 * @param[in]     isf_past         Past frame final isf vector
 */
static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,
                         const float *exc, const float *isf, const float *isf_past)
{
    float hb_lpc[LP_ORDER_16k];
    enum Mode mode = ctx->fr_cur_mode;

    if (mode == MODE_6k60) {
        float e_isf[LP_ORDER_16k]; // ISF vector for extrapolation
        double e_isp[LP_ORDER_16k];

        ctx->acelpv_ctx.weighted_vector_sumf(e_isf, isf_past, isf, isfp_inter[subframe],
                                1.0 - isfp_inter[subframe], LP_ORDER);

        extrapolate_isf(e_isf);

        e_isf[LP_ORDER_16k - 1] *= 2.0;
        ff_acelp_lsf2lspd(e_isp, e_isf, LP_ORDER_16k);
        ff_amrwb_lsp2lpc(e_isp, hb_lpc, LP_ORDER_16k);

        lpc_weighting(hb_lpc, hb_lpc, 0.9, LP_ORDER_16k);
    } else {
        lpc_weighting(hb_lpc, ctx->lp_coef[subframe], 0.6, LP_ORDER);
    }

    ctx->celpf_ctx.celp_lp_synthesis_filterf(samples, hb_lpc, exc, AMRWB_SFR_SIZE_16k,
                                 (mode == MODE_6k60) ? LP_ORDER_16k : LP_ORDER);
}

/**
 * Apply a 15th order filter to high-band samples.
 * The filter characteristic depends on the given coefficients.
 *
 * @param[out]    out              Buffer for filtered output
 * @param[in]     fir_coef         Filter coefficients
 * @param[in,out] mem              State from last filtering (updated)
 * @param[in]     in               Input speech data (high-band)
 *
 * @remark It is safe to pass the same array in in and out parameters
 */

#ifndef hb_fir_filter
static void hb_fir_filter(float *out, const float fir_coef[HB_FIR_SIZE + 1],
                          float mem[HB_FIR_SIZE], const float *in)
{
    int i, j;
    float data[AMRWB_SFR_SIZE_16k + HB_FIR_SIZE]; // past and current samples

    memcpy(data, mem, HB_FIR_SIZE * sizeof(float));
    memcpy(data + HB_FIR_SIZE, in, AMRWB_SFR_SIZE_16k * sizeof(float));

    for (i = 0; i < AMRWB_SFR_SIZE_16k; i++) {
        out[i] = 0.0;
        for (j = 0; j <= HB_FIR_SIZE; j++)
            out[i] += data[i + j] * fir_coef[j];
    }

    memcpy(mem, data + AMRWB_SFR_SIZE_16k, HB_FIR_SIZE * sizeof(float));
}
#endif /* hb_fir_filter */

/**
 * Update context state before the next subframe.
 */
static void update_sub_state(AMRWBContext *ctx)
{
    memmove(&ctx->excitation_buf[0], &ctx->excitation_buf[AMRWB_SFR_SIZE],
            (AMRWB_P_DELAY_MAX + LP_ORDER + 1) * sizeof(float));

    memmove(&ctx->pitch_gain[1], &ctx->pitch_gain[0], 5 * sizeof(float));
    memmove(&ctx->fixed_gain[1], &ctx->fixed_gain[0], 1 * sizeof(float));

    memmove(&ctx->samples_az[0], &ctx->samples_az[AMRWB_SFR_SIZE],
            LP_ORDER * sizeof(float));
    memmove(&ctx->samples_up[0], &ctx->samples_up[AMRWB_SFR_SIZE],
            UPS_MEM_SIZE * sizeof(float));
    memmove(&ctx->samples_hb[0], &ctx->samples_hb[AMRWB_SFR_SIZE_16k],
            LP_ORDER_16k * sizeof(float));
}

static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
{
    AMRWBContext *ctx  = avctx->priv_data;
    AVFrame *frame     = data;
    AMRWBFrame   *cf   = &ctx->frame;
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
    int expected_fr_size, header_size;
    float *buf_out;
    float spare_vector[AMRWB_SFR_SIZE];      // extra stack space to hold result from anti-sparseness processing
    float fixed_gain_factor;                 // fixed gain correction factor (gamma)
    float *synth_fixed_vector;               // pointer to the fixed vector that synthesis should use
    float synth_fixed_gain;                  // the fixed gain that synthesis should use
    float voice_fac, stab_fac;               // parameters used for gain smoothing
    float synth_exc[AMRWB_SFR_SIZE];         // post-processed excitation for synthesis
    float hb_exc[AMRWB_SFR_SIZE_16k];        // excitation for the high frequency band
    float hb_samples[AMRWB_SFR_SIZE_16k];    // filtered high-band samples from synthesis
    float hb_gain;
    int sub, i, ret;

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

    header_size      = decode_mime_header(ctx, buf);
    if (ctx->fr_cur_mode > MODE_SID) {
        av_log(avctx, AV_LOG_ERROR,
               "Invalid mode %d\n", ctx->fr_cur_mode);
        return AVERROR_INVALIDDATA;
    }
    expected_fr_size = ((cf_sizes_wb[ctx->fr_cur_mode] + 7) >> 3) + 1;

    if (buf_size < expected_fr_size) {
        av_log(avctx, AV_LOG_ERROR,
            "Frame too small (%d bytes). Truncated file?\n", buf_size);
        *got_frame_ptr = 0;
        return AVERROR_INVALIDDATA;
    }

    if (!ctx->fr_quality || ctx->fr_cur_mode > MODE_SID)
        av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n");

    if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */
        avpriv_request_sample(avctx, "SID mode");
        return AVERROR_PATCHWELCOME;
    }

    ff_amr_bit_reorder((uint16_t *) &ctx->frame, sizeof(AMRWBFrame),
        buf + header_size, amr_bit_orderings_by_mode[ctx->fr_cur_mode]);

    /* Decode the quantized ISF vector */
    if (ctx->fr_cur_mode == MODE_6k60) {
        decode_isf_indices_36b(cf->isp_id, ctx->isf_cur);
    } else {
        decode_isf_indices_46b(cf->isp_id, ctx->isf_cur);
    }

    isf_add_mean_and_past(ctx->isf_cur, ctx->isf_q_past);
    ff_set_min_dist_lsf(ctx->isf_cur, MIN_ISF_SPACING, LP_ORDER - 1);

    stab_fac = stability_factor(ctx->isf_cur, ctx->isf_past_final);

    ctx->isf_cur[LP_ORDER - 1] *= 2.0;
    ff_acelp_lsf2lspd(ctx->isp[3], ctx->isf_cur, LP_ORDER);

    /* Generate a ISP vector for each subframe */
    if (ctx->first_frame) {
        ctx->first_frame = 0;
        memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(double));
    }
    interpolate_isp(ctx->isp, ctx->isp_sub4_past);

    for (sub = 0; sub < 4; sub++)
        ff_amrwb_lsp2lpc(ctx->isp[sub], ctx->lp_coef[sub], LP_ORDER);

    for (sub = 0; sub < 4; sub++) {
        const AMRWBSubFrame *cur_subframe = &cf->subframe[sub];
        float *sub_buf = buf_out + sub * AMRWB_SFR_SIZE_16k;

        /* Decode adaptive codebook (pitch vector) */
        decode_pitch_vector(ctx, cur_subframe, sub);
        /* Decode innovative codebook (fixed vector) */
        decode_fixed_vector(ctx->fixed_vector, cur_subframe->pul_ih,
                            cur_subframe->pul_il, ctx->fr_cur_mode);

        pitch_sharpening(ctx, ctx->fixed_vector);

        decode_gains(cur_subframe->vq_gain, ctx->fr_cur_mode,
                     &fixed_gain_factor, &ctx->pitch_gain[0]);

        ctx->fixed_gain[0] =
            ff_amr_set_fixed_gain(fixed_gain_factor,
                                  ctx->celpm_ctx.dot_productf(ctx->fixed_vector,
                                                               ctx->fixed_vector,
                                                               AMRWB_SFR_SIZE) /
                                  AMRWB_SFR_SIZE,
                       ctx->prediction_error,
                       ENERGY_MEAN, energy_pred_fac);

        /* Calculate voice factor and store tilt for next subframe */
        voice_fac      = voice_factor(ctx->pitch_vector, ctx->pitch_gain[0],
                                      ctx->fixed_vector, ctx->fixed_gain[0],
                                      &ctx->celpm_ctx);
        ctx->tilt_coef = voice_fac * 0.25 + 0.25;

        /* Construct current excitation */
        for (i = 0; i < AMRWB_SFR_SIZE; i++) {
            ctx->excitation[i] *= ctx->pitch_gain[0];
            ctx->excitation[i] += ctx->fixed_gain[0] * ctx->fixed_vector[i];
            ctx->excitation[i] = truncf(ctx->excitation[i]);
        }

        /* Post-processing of excitation elements */
        synth_fixed_gain = noise_enhancer(ctx->fixed_gain[0], &ctx->prev_tr_gain,
                                          voice_fac, stab_fac);

        synth_fixed_vector = anti_sparseness(ctx, ctx->fixed_vector,
                                             spare_vector);

        pitch_enhancer(synth_fixed_vector, voice_fac);

        synthesis(ctx, ctx->lp_coef[sub], synth_exc, synth_fixed_gain,
                  synth_fixed_vector, &ctx->samples_az[LP_ORDER]);

        /* Synthesis speech post-processing */
        de_emphasis(&ctx->samples_up[UPS_MEM_SIZE],
                    &ctx->samples_az[LP_ORDER], PREEMPH_FAC, ctx->demph_mem);

        ctx->acelpf_ctx.acelp_apply_order_2_transfer_function(&ctx->samples_up[UPS_MEM_SIZE],
            &ctx->samples_up[UPS_MEM_SIZE], hpf_zeros, hpf_31_poles,
            hpf_31_gain, ctx->hpf_31_mem, AMRWB_SFR_SIZE);

        upsample_5_4(sub_buf, &ctx->samples_up[UPS_FIR_SIZE],
                     AMRWB_SFR_SIZE_16k, &ctx->celpm_ctx);

        /* High frequency band (6.4 - 7.0 kHz) generation part */
        ctx->acelpf_ctx.acelp_apply_order_2_transfer_function(hb_samples,
            &ctx->samples_up[UPS_MEM_SIZE], hpf_zeros, hpf_400_poles,
            hpf_400_gain, ctx->hpf_400_mem, AMRWB_SFR_SIZE);

        hb_gain = find_hb_gain(ctx, hb_samples,
                               cur_subframe->hb_gain, cf->vad);

        scaled_hb_excitation(ctx, hb_exc, synth_exc, hb_gain);

        hb_synthesis(ctx, sub, &ctx->samples_hb[LP_ORDER_16k],
                     hb_exc, ctx->isf_cur, ctx->isf_past_final);

        /* High-band post-processing filters */
        hb_fir_filter(hb_samples, bpf_6_7_coef, ctx->bpf_6_7_mem,
                      &ctx->samples_hb[LP_ORDER_16k]);

        if (ctx->fr_cur_mode == MODE_23k85)
            hb_fir_filter(hb_samples, lpf_7_coef, ctx->lpf_7_mem,
                          hb_samples);

        /* Add the low and high frequency bands */
        for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
            sub_buf[i] = (sub_buf[i] + hb_samples[i]) * (1.0f / (1 << 15));

        /* Update buffers and history */
        update_sub_state(ctx);
    }

    /* update state for next frame */
    memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0]));
    memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float));

    *got_frame_ptr = 1;

    return expected_fr_size;
}

AVCodec ff_amrwb_decoder = {
    .name           = "amrwb",
    .long_name      = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"),
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_AMR_WB,
    .priv_data_size = sizeof(AMRWBContext),
    .init           = amrwb_decode_init,
    .decode         = amrwb_decode_frame,
    .capabilities   = AV_CODEC_CAP_DR1,
    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
                                                     AV_SAMPLE_FMT_NONE },
};
