/*
 * 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 "celp_filters.h"
#include "internal.h"
#include "mathops.h"
#include "put_bits.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->initial_padding = 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_audiodsp_init(&ractx->adsp);
    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->adsp, 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)) < 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   = AV_CODEC_CAP_DELAY | AV_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 },
};
