/*
 * G.726 ADPCM audio codec
 * Copyright (c) 2004 Roman Shaposhnik
 *
 * This is a very straightforward rendition of the G.726
 * Section 4 "Computational Details".
 *
 * 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
 */
#include <limits.h>

#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
#include "put_bits.h"

/**
 * G.726 11bit float.
 * G.726 Standard uses rather odd 11bit floating point arithmentic for
 * numerous occasions. It's a mystery to me why they did it this way
 * instead of simply using 32bit integer arithmetic.
 */
typedef struct Float11 {
    uint8_t sign;   /**< 1bit sign */
    uint8_t exp;    /**< 4bit exponent */
    uint8_t mant;   /**< 6bit mantissa */
} Float11;

static inline Float11* i2f(int i, Float11* f)
{
    f->sign = (i < 0);
    if (f->sign)
        i = -i;
    f->exp = av_log2_16bit(i) + !!i;
    f->mant = i? (i<<6) >> f->exp : 1<<5;
    return f;
}

static inline int16_t mult(Float11* f1, Float11* f2)
{
        int res, exp;

        exp = f1->exp + f2->exp;
        res = (((f1->mant * f2->mant) + 0x30) >> 4);
        res = exp > 19 ? res << (exp - 19) : res >> (19 - exp);
        return (f1->sign ^ f2->sign) ? -res : res;
}

static inline int sgn(int value)
{
    return (value < 0) ? -1 : 1;
}

typedef struct G726Tables {
    const int* quant;         /**< quantization table */
    const int16_t* iquant;    /**< inverse quantization table */
    const int16_t* W;         /**< special table #1 ;-) */
    const uint8_t* F;         /**< special table #2 */
} G726Tables;

typedef struct G726Context {
    AVClass *class;
    G726Tables tbls;    /**< static tables needed for computation */

    Float11 sr[2];      /**< prev. reconstructed samples */
    Float11 dq[6];      /**< prev. difference */
    int a[2];           /**< second order predictor coeffs */
    int b[6];           /**< sixth order predictor coeffs */
    int pk[2];          /**< signs of prev. 2 sez + dq */

    int ap;             /**< scale factor control */
    int yu;             /**< fast scale factor */
    int yl;             /**< slow scale factor */
    int dms;            /**< short average magnitude of F[i] */
    int dml;            /**< long average magnitude of F[i] */
    int td;             /**< tone detect */

    int se;             /**< estimated signal for the next iteration */
    int sez;            /**< estimated second order prediction */
    int y;              /**< quantizer scaling factor for the next iteration */
    int code_size;
    int little_endian;  /**< little-endian bitstream as used in aiff and Sun AU */
} G726Context;

static const int quant_tbl16[] =                  /**< 16kbit/s 2bits per sample */
           { 260, INT_MAX };
static const int16_t iquant_tbl16[] =
           { 116, 365, 365, 116 };
static const int16_t W_tbl16[] =
           { -22, 439, 439, -22 };
static const uint8_t F_tbl16[] =
           { 0, 7, 7, 0 };

static const int quant_tbl24[] =                  /**< 24kbit/s 3bits per sample */
           {  7, 217, 330, INT_MAX };
static const int16_t iquant_tbl24[] =
           { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN };
static const int16_t W_tbl24[] =
           { -4,  30, 137, 582, 582, 137,  30, -4 };
static const uint8_t F_tbl24[] =
           { 0, 1, 2, 7, 7, 2, 1, 0 };

static const int quant_tbl32[] =                  /**< 32kbit/s 4bits per sample */
           { -125,  79, 177, 245, 299, 348, 399, INT_MAX };
static const int16_t iquant_tbl32[] =
         { INT16_MIN,   4, 135, 213, 273, 323, 373, 425,
                 425, 373, 323, 273, 213, 135,   4, INT16_MIN };
static const int16_t W_tbl32[] =
           { -12,  18,  41,  64, 112, 198, 355, 1122,
            1122, 355, 198, 112,  64,  41,  18, -12};
static const uint8_t F_tbl32[] =
           { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 };

static const int quant_tbl40[] =                  /**< 40kbit/s 5bits per sample */
           { -122, -16,  67, 138, 197, 249, 297, 338,
              377, 412, 444, 474, 501, 527, 552, INT_MAX };
static const int16_t iquant_tbl40[] =
         { INT16_MIN, -66,  28, 104, 169, 224, 274, 318,
                 358, 395, 429, 459, 488, 514, 539, 566,
                 566, 539, 514, 488, 459, 429, 395, 358,
                 318, 274, 224, 169, 104,  28, -66, INT16_MIN };
static const int16_t W_tbl40[] =
           {   14,  14,  24,  39,  40,  41,   58,  100,
              141, 179, 219, 280, 358, 440,  529,  696,
              696, 529, 440, 358, 280, 219,  179,  141,
              100,  58,  41,  40,  39,  24,   14,   14 };
static const uint8_t F_tbl40[] =
           { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6,
             6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };

static const G726Tables G726Tables_pool[] =
           {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 },
            { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 },
            { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 },
            { quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }};


/**
 * Para 4.2.2 page 18: Adaptive quantizer.
 */
static inline uint8_t quant(G726Context* c, int d)
{
    int sign, exp, i, dln;

    sign = i = 0;
    if (d < 0) {
        sign = 1;
        d = -d;
    }
    exp = av_log2_16bit(d);
    dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2);

    while (c->tbls.quant[i] < INT_MAX && c->tbls.quant[i] < dln)
        ++i;

    if (sign)
        i = ~i;
    if (c->code_size != 2 && i == 0) /* I'm not sure this is a good idea */
        i = 0xff;

    return i;
}

/**
 * Para 4.2.3 page 22: Inverse adaptive quantizer.
 */
static inline int16_t inverse_quant(G726Context* c, int i)
{
    int dql, dex, dqt;

    dql = c->tbls.iquant[i] + (c->y >> 2);
    dex = (dql>>7) & 0xf;        /* 4bit exponent */
    dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */
    return (dql < 0) ? 0 : ((dqt<<dex) >> 7);
}

static int16_t g726_decode(G726Context* c, int I)
{
    int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0;
    Float11 f;
    int I_sig= I >> (c->code_size - 1);

    dq = inverse_quant(c, I);

    /* Transition detect */
    ylint = (c->yl >> 15);
    ylfrac = (c->yl >> 10) & 0x1f;
    thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint;
    tr= (c->td == 1 && dq > ((3*thr2)>>2));

    if (I_sig)  /* get the sign */
        dq = -dq;
    re_signal = c->se + dq;

    /* Update second order predictor coefficient A2 and A1 */
    pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0;
    dq0 = dq ? sgn(dq) : 0;
    if (tr) {
        c->a[0] = 0;
        c->a[1] = 0;
        for (i=0; i<6; i++)
            c->b[i] = 0;
    } else {
        /* This is a bit crazy, but it really is +255 not +256 */
        fa1 = av_clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255);

        c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7);
        c->a[1] = av_clip(c->a[1], -12288, 12288);
        c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8);
        c->a[0] = av_clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]);

        for (i=0; i<6; i++)
            c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8);
    }

    /* Update Dq and Sr and Pk */
    c->pk[1] = c->pk[0];
    c->pk[0] = pk0 ? pk0 : 1;
    c->sr[1] = c->sr[0];
    i2f(re_signal, &c->sr[0]);
    for (i=5; i>0; i--)
        c->dq[i] = c->dq[i-1];
    i2f(dq, &c->dq[0]);
    c->dq[0].sign = I_sig; /* Isn't it crazy ?!?! */

    c->td = c->a[1] < -11776;

    /* Update Ap */
    c->dms += (c->tbls.F[I]<<4) + ((- c->dms) >> 5);
    c->dml += (c->tbls.F[I]<<4) + ((- c->dml) >> 7);
    if (tr)
        c->ap = 256;
    else {
        c->ap += (-c->ap) >> 4;
        if (c->y <= 1535 || c->td || abs((c->dms << 2) - c->dml) >= (c->dml >> 3))
            c->ap += 0x20;
    }

    /* Update Yu and Yl */
    c->yu = av_clip(c->y + c->tbls.W[I] + ((-c->y)>>5), 544, 5120);
    c->yl += c->yu + ((-c->yl)>>6);

    /* Next iteration for Y */
    al = (c->ap >= 256) ? 1<<6 : c->ap >> 2;
    c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6;

    /* Next iteration for SE and SEZ */
    c->se = 0;
    for (i=0; i<6; i++)
        c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]);
    c->sez = c->se >> 1;
    for (i=0; i<2; i++)
        c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]);
    c->se >>= 1;

    return av_clip(re_signal << 2, -0xffff, 0xffff);
}

static av_cold int g726_reset(G726Context *c)
{
    int i;

    c->tbls = G726Tables_pool[c->code_size - 2];
    for (i=0; i<2; i++) {
        c->sr[i].mant = 1<<5;
        c->pk[i] = 1;
    }
    for (i=0; i<6; i++) {
        c->dq[i].mant = 1<<5;
    }
    c->yu = 544;
    c->yl = 34816;

    c->y = 544;

    return 0;
}

#if CONFIG_ADPCM_G726_ENCODER
static int16_t g726_encode(G726Context* c, int16_t sig)
{
    uint8_t i;

    i = quant(c, sig/4 - c->se) & ((1<<c->code_size) - 1);
    g726_decode(c, i);
    return i;
}

/* Interfacing to the libavcodec */

static av_cold int g726_encode_init(AVCodecContext *avctx)
{
    G726Context* c = avctx->priv_data;

    if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL &&
        avctx->sample_rate != 8000) {
        av_log(avctx, AV_LOG_ERROR, "Sample rates other than 8kHz are not "
               "allowed when the compliance level is higher than unofficial. "
               "Resample or reduce the compliance level.\n");
        return AVERROR(EINVAL);
    }
    av_assert0(avctx->sample_rate > 0);

    if(avctx->channels != 1){
        av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
        return AVERROR(EINVAL);
    }

    if (avctx->bit_rate)
        c->code_size = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate;

    c->code_size = av_clip(c->code_size, 2, 5);
    avctx->bit_rate = c->code_size * avctx->sample_rate;
    avctx->bits_per_coded_sample = c->code_size;

    g726_reset(c);

    /* select a frame size that will end on a byte boundary and have a size of
       approximately 1024 bytes */
    avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[c->code_size - 2];

    return 0;
}

static int g726_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                             const AVFrame *frame, int *got_packet_ptr)
{
    G726Context *c = avctx->priv_data;
    const int16_t *samples = (const int16_t *)frame->data[0];
    PutBitContext pb;
    int i, ret, out_size;

    out_size = (frame->nb_samples * c->code_size + 7) / 8;
    if ((ret = ff_alloc_packet2(avctx, avpkt, out_size)) < 0)
        return ret;
    init_put_bits(&pb, avpkt->data, avpkt->size);

    for (i = 0; i < frame->nb_samples; i++)
        put_bits(&pb, c->code_size, g726_encode(c, *samples++));

    flush_put_bits(&pb);

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

#define OFFSET(x) offsetof(G726Context, x)
#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
    { "code_size", "Bits per code", OFFSET(code_size), AV_OPT_TYPE_INT, { .i64 = 4 }, 2, 5, AE },
    { NULL },
};

static const AVClass g726_class = {
    .class_name = "g726",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

static const AVCodecDefault defaults[] = {
    { "b", "0" },
    { NULL },
};

AVCodec ff_adpcm_g726_encoder = {
    .name           = "g726",
    .long_name      = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_ADPCM_G726,
    .priv_data_size = sizeof(G726Context),
    .init           = g726_encode_init,
    .encode2        = g726_encode_frame,
    .capabilities   = CODEC_CAP_SMALL_LAST_FRAME,
    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                     AV_SAMPLE_FMT_NONE },
    .priv_class     = &g726_class,
    .defaults       = defaults,
};
#endif

#if CONFIG_ADPCM_G726_DECODER || CONFIG_ADPCM_G726LE_DECODER
static av_cold int g726_decode_init(AVCodecContext *avctx)
{
    G726Context* c = avctx->priv_data;

    if(avctx->channels > 1){
        avpriv_request_sample(avctx, "Decoding more than one channel");
        return AVERROR_PATCHWELCOME;
    }
    avctx->channels       = 1;
    avctx->channel_layout = AV_CH_LAYOUT_MONO;

    c->little_endian = !strcmp(avctx->codec->name, "g726le");

    c->code_size = avctx->bits_per_coded_sample;
    if (c->code_size < 2 || c->code_size > 5) {
        av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size);
        return AVERROR(EINVAL);
    }
    g726_reset(c);

    avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    return 0;
}

static int g726_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
{
    AVFrame *frame     = data;
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    G726Context *c = avctx->priv_data;
    int16_t *samples;
    GetBitContext gb;
    int out_samples, ret;

    out_samples = buf_size * 8 / c->code_size;

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

    init_get_bits(&gb, buf, buf_size * 8);

    while (out_samples--)
        *samples++ = g726_decode(c, c->little_endian ?
                                    get_bits_le(&gb, c->code_size) :
                                    get_bits(&gb, c->code_size));

    if (get_bits_left(&gb) > 0)
        av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n");

    *got_frame_ptr = 1;

    return buf_size;
}

static void g726_decode_flush(AVCodecContext *avctx)
{
    G726Context *c = avctx->priv_data;
    g726_reset(c);
}
#endif

#if CONFIG_ADPCM_G726_DECODER
AVCodec ff_adpcm_g726_decoder = {
    .name           = "g726",
    .long_name      = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_ADPCM_G726,
    .priv_data_size = sizeof(G726Context),
    .init           = g726_decode_init,
    .decode         = g726_decode_frame,
    .flush          = g726_decode_flush,
    .capabilities   = CODEC_CAP_DR1,
};
#endif

#if CONFIG_ADPCM_G726LE_DECODER
AVCodec ff_adpcm_g726le_decoder = {
    .name           = "g726le",
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_ADPCM_G726LE,
    .priv_data_size = sizeof(G726Context),
    .init           = g726_decode_init,
    .decode         = g726_decode_frame,
    .flush          = g726_decode_flush,
    .capabilities   = CODEC_CAP_DR1,
    .long_name      = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"),
};
#endif
