/*
 * Real Audio 1.0 (14.4K) encoder
 * Copyright (c) 2010 Francesco Lavra <francescolavra@interfree.it>
 *
 * 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
 * Real Audio 1.0 (14.4K) encoder
 * @author Francesco Lavra <francescolavra@interfree.it>
 */

#include <float.h>

#include "avcodec.h"
#include "audio_frame_queue.h"
#include "internal.h"
#include "put_bits.h"
#include "celp_filters.h"
#include "ra144.h"

static av_cold int ra144_encode_close(AVCodecContext *avctx)
{
    RA144Context *ractx = avctx->priv_data;
    ff_lpc_end(&ractx->lpc_ctx);
    ff_af_queue_close(&ractx->afq);
    return 0;
}


static av_cold int ra144_encode_init(AVCodecContext * avctx)
{
    RA144Context *ractx;
    int ret;

    if (avctx->channels != 1) {
        av_log(avctx, AV_LOG_ERROR, "invalid number of channels: %d\n",
               avctx->channels);
        return -1;
    }
    avctx->frame_size = NBLOCKS * BLOCKSIZE;
    avctx->delay      = avctx->frame_size;
    avctx->bit_rate = 8000;
    ractx = avctx->priv_data;
    ractx->lpc_coef[0] = ractx->lpc_tables[0];
    ractx->lpc_coef[1] = ractx->lpc_tables[1];
    ractx->avctx = avctx;
    ff_dsputil_init(&ractx->dsp, avctx);
    ret = ff_lpc_init(&ractx->lpc_ctx, avctx->frame_size, LPC_ORDER,
                      FF_LPC_TYPE_LEVINSON);
    if (ret < 0)
        goto error;

    ff_af_queue_init(avctx, &ractx->afq);

    return 0;
error:
    ra144_encode_close(avctx);
    return ret;
}


/**
 * Quantize a value by searching a sorted table for the element with the
 * nearest value
 *
 * @param value value to quantize
 * @param table array containing the quantization table
 * @param size size of the quantization table
 * @return index of the quantization table corresponding to the element with the
 *         nearest value
 */
static int quantize(int value, const int16_t *table, unsigned int size)
{
    unsigned int low = 0, high = size - 1;

    while (1) {
        int index = (low + high) >> 1;
        int error = table[index] - value;

        if (index == low)
            return table[high] + error > value ? low : high;
        if (error > 0) {
            high = index;
        } else {
            low = index;
        }
    }
}


/**
 * Orthogonalize a vector to another vector
 *
 * @param v vector to orthogonalize
 * @param u vector against which orthogonalization is performed
 */
static void orthogonalize(float *v, const float *u)
{
    int i;
    float num = 0, den = 0;

    for (i = 0; i < BLOCKSIZE; i++) {
        num += v[i] * u[i];
        den += u[i] * u[i];
    }
    num /= den;
    for (i = 0; i < BLOCKSIZE; i++)
        v[i] -= num * u[i];
}


/**
 * Calculate match score and gain of an LPC-filtered vector with respect to
 * input data, possibly othogonalizing it to up to 2 other vectors
 *
 * @param work array used to calculate the filtered vector
 * @param coefs coefficients of the LPC filter
 * @param vect original vector
 * @param ortho1 first vector against which orthogonalization is performed
 * @param ortho2 second vector against which orthogonalization is performed
 * @param data input data
 * @param score pointer to variable where match score is returned
 * @param gain pointer to variable where gain is returned
 */
static void get_match_score(float *work, const float *coefs, float *vect,
                            const float *ortho1, const float *ortho2,
                            const float *data, float *score, float *gain)
{
    float c, g;
    int i;

    ff_celp_lp_synthesis_filterf(work, coefs, vect, BLOCKSIZE, LPC_ORDER);
    if (ortho1)
        orthogonalize(work, ortho1);
    if (ortho2)
        orthogonalize(work, ortho2);
    c = g = 0;
    for (i = 0; i < BLOCKSIZE; i++) {
        g += work[i] * work[i];
        c += data[i] * work[i];
    }
    if (c <= 0) {
        *score = 0;
        return;
    }
    *gain = c / g;
    *score = *gain * c;
}


/**
 * Create a vector from the adaptive codebook at a given lag value
 *
 * @param vect array where vector is stored
 * @param cb adaptive codebook
 * @param lag lag value
 */
static void create_adapt_vect(float *vect, const int16_t *cb, int lag)
{
    int i;

    cb += BUFFERSIZE - lag;
    for (i = 0; i < FFMIN(BLOCKSIZE, lag); i++)
        vect[i] = cb[i];
    if (lag < BLOCKSIZE)
        for (i = 0; i < BLOCKSIZE - lag; i++)
            vect[lag + i] = cb[i];
}


/**
 * Search the adaptive codebook for the best entry and gain and remove its
 * contribution from input data
 *
 * @param adapt_cb array from which the adaptive codebook is extracted
 * @param work array used to calculate LPC-filtered vectors
 * @param coefs coefficients of the LPC filter
 * @param data input data
 * @return index of the best entry of the adaptive codebook
 */
static int adaptive_cb_search(const int16_t *adapt_cb, float *work,
                              const float *coefs, float *data)
{
    int i, av_uninit(best_vect);
    float score, gain, best_score, av_uninit(best_gain);
    float exc[BLOCKSIZE];

    gain = best_score = 0;
    for (i = BLOCKSIZE / 2; i <= BUFFERSIZE; i++) {
        create_adapt_vect(exc, adapt_cb, i);
        get_match_score(work, coefs, exc, NULL, NULL, data, &score, &gain);
        if (score > best_score) {
            best_score = score;
            best_vect = i;
            best_gain = gain;
        }
    }
    if (!best_score)
        return 0;

    /**
     * Re-calculate the filtered vector from the vector with maximum match score
     * and remove its contribution from input data.
     */
    create_adapt_vect(exc, adapt_cb, best_vect);
    ff_celp_lp_synthesis_filterf(work, coefs, exc, BLOCKSIZE, LPC_ORDER);
    for (i = 0; i < BLOCKSIZE; i++)
        data[i] -= best_gain * work[i];
    return best_vect - BLOCKSIZE / 2 + 1;
}


/**
 * Find the best vector of a fixed codebook by applying an LPC filter to
 * codebook entries, possibly othogonalizing them to up to 2 other vectors and
 * matching the results with input data
 *
 * @param work array used to calculate the filtered vectors
 * @param coefs coefficients of the LPC filter
 * @param cb fixed codebook
 * @param ortho1 first vector against which orthogonalization is performed
 * @param ortho2 second vector against which orthogonalization is performed
 * @param data input data
 * @param idx pointer to variable where the index of the best codebook entry is
 *        returned
 * @param gain pointer to variable where the gain of the best codebook entry is
 *        returned
 */
static void find_best_vect(float *work, const float *coefs,
                           const int8_t cb[][BLOCKSIZE], const float *ortho1,
                           const float *ortho2, float *data, int *idx,
                           float *gain)
{
    int i, j;
    float g, score, best_score;
    float vect[BLOCKSIZE];

    *idx = *gain = best_score = 0;
    for (i = 0; i < FIXED_CB_SIZE; i++) {
        for (j = 0; j < BLOCKSIZE; j++)
            vect[j] = cb[i][j];
        get_match_score(work, coefs, vect, ortho1, ortho2, data, &score, &g);
        if (score > best_score) {
            best_score = score;
            *idx = i;
            *gain = g;
        }
    }
}


/**
 * Search the two fixed codebooks for the best entry and gain
 *
 * @param work array used to calculate LPC-filtered vectors
 * @param coefs coefficients of the LPC filter
 * @param data input data
 * @param cba_idx index of the best entry of the adaptive codebook
 * @param cb1_idx pointer to variable where the index of the best entry of the
 *        first fixed codebook is returned
 * @param cb2_idx pointer to variable where the index of the best entry of the
 *        second fixed codebook is returned
 */
static void fixed_cb_search(float *work, const float *coefs, float *data,
                            int cba_idx, int *cb1_idx, int *cb2_idx)
{
    int i, ortho_cb1;
    float gain;
    float cba_vect[BLOCKSIZE], cb1_vect[BLOCKSIZE];
    float vect[BLOCKSIZE];

    /**
     * The filtered vector from the adaptive codebook can be retrieved from
     * work, because this function is called just after adaptive_cb_search().
     */
    if (cba_idx)
        memcpy(cba_vect, work, sizeof(cba_vect));

    find_best_vect(work, coefs, ff_cb1_vects, cba_idx ? cba_vect : NULL, NULL,
                   data, cb1_idx, &gain);

    /**
     * Re-calculate the filtered vector from the vector with maximum match score
     * and remove its contribution from input data.
     */
    if (gain) {
        for (i = 0; i < BLOCKSIZE; i++)
            vect[i] = ff_cb1_vects[*cb1_idx][i];
        ff_celp_lp_synthesis_filterf(work, coefs, vect, BLOCKSIZE, LPC_ORDER);
        if (cba_idx)
            orthogonalize(work, cba_vect);
        for (i = 0; i < BLOCKSIZE; i++)
            data[i] -= gain * work[i];
        memcpy(cb1_vect, work, sizeof(cb1_vect));
        ortho_cb1 = 1;
    } else
        ortho_cb1 = 0;

    find_best_vect(work, coefs, ff_cb2_vects, cba_idx ? cba_vect : NULL,
                   ortho_cb1 ? cb1_vect : NULL, data, cb2_idx, &gain);
}


/**
 * Encode a subblock of the current frame
 *
 * @param ractx encoder context
 * @param sblock_data input data of the subblock
 * @param lpc_coefs coefficients of the LPC filter
 * @param rms RMS of the reflection coefficients
 * @param pb pointer to PutBitContext of the current frame
 */
static void ra144_encode_subblock(RA144Context *ractx,
                                  const int16_t *sblock_data,
                                  const int16_t *lpc_coefs, unsigned int rms,
                                  PutBitContext *pb)
{
    float data[BLOCKSIZE] = { 0 }, work[LPC_ORDER + BLOCKSIZE];
    float coefs[LPC_ORDER];
    float zero[BLOCKSIZE], cba[BLOCKSIZE], cb1[BLOCKSIZE], cb2[BLOCKSIZE];
    int cba_idx, cb1_idx, cb2_idx, gain;
    int i, n;
    unsigned m[3];
    float g[3];
    float error, best_error;

    for (i = 0; i < LPC_ORDER; i++) {
        work[i] = ractx->curr_sblock[BLOCKSIZE + i];
        coefs[i] = lpc_coefs[i] * (1/4096.0);
    }

    /**
     * Calculate the zero-input response of the LPC filter and subtract it from
     * input data.
     */
    ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, data, BLOCKSIZE,
                                 LPC_ORDER);
    for (i = 0; i < BLOCKSIZE; i++) {
        zero[i] = work[LPC_ORDER + i];
        data[i] = sblock_data[i] - zero[i];
    }

    /**
     * Codebook search is performed without taking into account the contribution
     * of the previous subblock, since it has been just subtracted from input
     * data.
     */
    memset(work, 0, LPC_ORDER * sizeof(*work));

    cba_idx = adaptive_cb_search(ractx->adapt_cb, work + LPC_ORDER, coefs,
                                 data);
    if (cba_idx) {
        /**
         * The filtered vector from the adaptive codebook can be retrieved from
         * work, see implementation of adaptive_cb_search().
         */
        memcpy(cba, work + LPC_ORDER, sizeof(cba));

        ff_copy_and_dup(ractx->buffer_a, ractx->adapt_cb, cba_idx + BLOCKSIZE / 2 - 1);
        m[0] = (ff_irms(&ractx->dsp, ractx->buffer_a) * rms) >> 12;
    }
    fixed_cb_search(work + LPC_ORDER, coefs, data, cba_idx, &cb1_idx, &cb2_idx);
    for (i = 0; i < BLOCKSIZE; i++) {
        cb1[i] = ff_cb1_vects[cb1_idx][i];
        cb2[i] = ff_cb2_vects[cb2_idx][i];
    }
    ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, cb1, BLOCKSIZE,
                                 LPC_ORDER);
    memcpy(cb1, work + LPC_ORDER, sizeof(cb1));
    m[1] = (ff_cb1_base[cb1_idx] * rms) >> 8;
    ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, cb2, BLOCKSIZE,
                                 LPC_ORDER);
    memcpy(cb2, work + LPC_ORDER, sizeof(cb2));
    m[2] = (ff_cb2_base[cb2_idx] * rms) >> 8;
    best_error = FLT_MAX;
    gain = 0;
    for (n = 0; n < 256; n++) {
        g[1] = ((ff_gain_val_tab[n][1] * m[1]) >> ff_gain_exp_tab[n]) *
               (1/4096.0);
        g[2] = ((ff_gain_val_tab[n][2] * m[2]) >> ff_gain_exp_tab[n]) *
               (1/4096.0);
        error = 0;
        if (cba_idx) {
            g[0] = ((ff_gain_val_tab[n][0] * m[0]) >> ff_gain_exp_tab[n]) *
                   (1/4096.0);
            for (i = 0; i < BLOCKSIZE; i++) {
                data[i] = zero[i] + g[0] * cba[i] + g[1] * cb1[i] +
                          g[2] * cb2[i];
                error += (data[i] - sblock_data[i]) *
                         (data[i] - sblock_data[i]);
            }
        } else {
            for (i = 0; i < BLOCKSIZE; i++) {
                data[i] = zero[i] + g[1] * cb1[i] + g[2] * cb2[i];
                error += (data[i] - sblock_data[i]) *
                         (data[i] - sblock_data[i]);
            }
        }
        if (error < best_error) {
            best_error = error;
            gain = n;
        }
    }
    put_bits(pb, 7, cba_idx);
    put_bits(pb, 8, gain);
    put_bits(pb, 7, cb1_idx);
    put_bits(pb, 7, cb2_idx);
    ff_subblock_synthesis(ractx, lpc_coefs, cba_idx, cb1_idx, cb2_idx, rms,
                          gain);
}


static int ra144_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                              const AVFrame *frame, int *got_packet_ptr)
{
    static const uint8_t sizes[LPC_ORDER] = {64, 32, 32, 16, 16, 8, 8, 8, 8, 4};
    static const uint8_t bit_sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
    RA144Context *ractx = avctx->priv_data;
    PutBitContext pb;
    int32_t lpc_data[NBLOCKS * BLOCKSIZE];
    int32_t lpc_coefs[LPC_ORDER][MAX_LPC_ORDER];
    int shift[LPC_ORDER];
    int16_t block_coefs[NBLOCKS][LPC_ORDER];
    int lpc_refl[LPC_ORDER];    /**< reflection coefficients of the frame */
    unsigned int refl_rms[NBLOCKS]; /**< RMS of the reflection coefficients */
    const int16_t *samples = frame ? (const int16_t *)frame->data[0] : NULL;
    int energy = 0;
    int i, idx, ret;

    if (ractx->last_frame)
        return 0;

    if ((ret = ff_alloc_packet2(avctx, avpkt, FRAME_SIZE)) < 0)
        return ret;

    /**
     * Since the LPC coefficients are calculated on a frame centered over the
     * fourth subframe, to encode a given frame, data from the next frame is
     * needed. In each call to this function, the previous frame (whose data are
     * saved in the encoder context) is encoded, and data from the current frame
     * are saved in the encoder context to be used in the next function call.
     */
    for (i = 0; i < (2 * BLOCKSIZE + BLOCKSIZE / 2); i++) {
        lpc_data[i] = ractx->curr_block[BLOCKSIZE + BLOCKSIZE / 2 + i];
        energy += (lpc_data[i] * lpc_data[i]) >> 4;
    }
    if (frame) {
        int j;
        for (j = 0; j < frame->nb_samples && i < NBLOCKS * BLOCKSIZE; i++, j++) {
            lpc_data[i] = samples[j] >> 2;
            energy += (lpc_data[i] * lpc_data[i]) >> 4;
        }
    }
    if (i < NBLOCKS * BLOCKSIZE)
        memset(&lpc_data[i], 0, (NBLOCKS * BLOCKSIZE - i) * sizeof(*lpc_data));
    energy = ff_energy_tab[quantize(ff_t_sqrt(energy >> 5) >> 10, ff_energy_tab,
                                    32)];

    ff_lpc_calc_coefs(&ractx->lpc_ctx, lpc_data, NBLOCKS * BLOCKSIZE, LPC_ORDER,
                      LPC_ORDER, 16, lpc_coefs, shift, FF_LPC_TYPE_LEVINSON,
                      0, ORDER_METHOD_EST, 12, 0);
    for (i = 0; i < LPC_ORDER; i++)
        block_coefs[NBLOCKS - 1][i] = -(lpc_coefs[LPC_ORDER - 1][i] <<
                                        (12 - shift[LPC_ORDER - 1]));

    /**
     * TODO: apply perceptual weighting of the input speech through bandwidth
     * expansion of the LPC filter.
     */

    if (ff_eval_refl(lpc_refl, block_coefs[NBLOCKS - 1], avctx)) {
        /**
         * The filter is unstable: use the coefficients of the previous frame.
         */
        ff_int_to_int16(block_coefs[NBLOCKS - 1], ractx->lpc_coef[1]);
        if (ff_eval_refl(lpc_refl, block_coefs[NBLOCKS - 1], avctx)) {
            /* the filter is still unstable. set reflection coeffs to zero. */
            memset(lpc_refl, 0, sizeof(lpc_refl));
        }
    }
    init_put_bits(&pb, avpkt->data, avpkt->size);
    for (i = 0; i < LPC_ORDER; i++) {
        idx = quantize(lpc_refl[i], ff_lpc_refl_cb[i], sizes[i]);
        put_bits(&pb, bit_sizes[i], idx);
        lpc_refl[i] = ff_lpc_refl_cb[i][idx];
    }
    ractx->lpc_refl_rms[0] = ff_rms(lpc_refl);
    ff_eval_coefs(ractx->lpc_coef[0], lpc_refl);
    refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy);
    refl_rms[1] = ff_interp(ractx, block_coefs[1], 2,
                            energy <= ractx->old_energy,
                            ff_t_sqrt(energy * ractx->old_energy) >> 12);
    refl_rms[2] = ff_interp(ractx, block_coefs[2], 3, 0, energy);
    refl_rms[3] = ff_rescale_rms(ractx->lpc_refl_rms[0], energy);
    ff_int_to_int16(block_coefs[NBLOCKS - 1], ractx->lpc_coef[0]);
    put_bits(&pb, 5, quantize(energy, ff_energy_tab, 32));
    for (i = 0; i < NBLOCKS; i++)
        ra144_encode_subblock(ractx, ractx->curr_block + i * BLOCKSIZE,
                              block_coefs[i], refl_rms[i], &pb);
    flush_put_bits(&pb);
    ractx->old_energy = energy;
    ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0];
    FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);

    /* copy input samples to current block for processing in next call */
    i = 0;
    if (frame) {
        for (; i < frame->nb_samples; i++)
            ractx->curr_block[i] = samples[i] >> 2;

        if ((ret = ff_af_queue_add(&ractx->afq, frame)) < 0)
            return ret;
    } else
        ractx->last_frame = 1;
    memset(&ractx->curr_block[i], 0,
           (NBLOCKS * BLOCKSIZE - i) * sizeof(*ractx->curr_block));

    /* Get the next frame pts/duration */
    ff_af_queue_remove(&ractx->afq, avctx->frame_size, &avpkt->pts,
                       &avpkt->duration);

    avpkt->size = FRAME_SIZE;
    *got_packet_ptr = 1;
    return 0;
}


AVCodec ff_ra_144_encoder = {
    .name           = "real_144",
    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_RA_144,
    .priv_data_size = sizeof(RA144Context),
    .init           = ra144_encode_init,
    .encode2        = ra144_encode_frame,
    .close          = ra144_encode_close,
    .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME,
    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                     AV_SAMPLE_FMT_NONE },
    .supported_samplerates = (const int[]){ 8000, 0 },
    .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
};
