/*
 * NellyMoser audio decoder
 * Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5,
 *                    539459aeb7d425140b62a3ec7dbf6dc8e408a306, and
 *                    520e17cd55896441042b14df2566a6eb610ed444
 * Copyright (c) 2007 Loic Minier <lool at dooz.org>
 *                    Benjamin Larsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * @file libavcodec/nellymoserdec.c
 * The 3 alphanumeric copyright notices are md5summed they are from the original
 * implementors. The original code is available from http://code.google.com/p/nelly2pcm/
 */

#include "nellymoser.h"
#include "libavutil/random.h"
#include "avcodec.h"
#include "dsputil.h"

#define ALT_BITSTREAM_READER_LE
#include "bitstream.h"


typedef struct NellyMoserDecodeContext {
    AVCodecContext* avctx;
    DECLARE_ALIGNED_16(float,float_buf[NELLY_SAMPLES]);
    float           state[128];
    AVRandomState   random_state;
    GetBitContext   gb;
    int             add_bias;
    float           scale_bias;
    DSPContext      dsp;
    MDCTContext     imdct_ctx;
    DECLARE_ALIGNED_16(float,imdct_out[NELLY_BUF_LEN * 2]);
} NellyMoserDecodeContext;

static void overlap_and_window(NellyMoserDecodeContext *s, float *state, float *audio, float *a_in)
{
    int bot, top;

    bot = 0;
    top = NELLY_BUF_LEN-1;

    while (bot < NELLY_BUF_LEN) {
        audio[bot] = a_in [bot]*ff_sine_128[bot]
                    +state[bot]*ff_sine_128[top] + s->add_bias;

        bot++;
        top--;
    }
    memcpy(state, a_in + NELLY_BUF_LEN, sizeof(float)*NELLY_BUF_LEN);
}

static void nelly_decode_block(NellyMoserDecodeContext *s,
                               const unsigned char block[NELLY_BLOCK_LEN],
                               float audio[NELLY_SAMPLES])
{
    int i,j;
    float buf[NELLY_FILL_LEN], pows[NELLY_FILL_LEN];
    float *aptr, *bptr, *pptr, val, pval;
    int bits[NELLY_BUF_LEN];
    unsigned char v;

    init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8);

    bptr = buf;
    pptr = pows;
    val = ff_nelly_init_table[get_bits(&s->gb, 6)];
    for (i=0 ; i<NELLY_BANDS ; i++) {
        if (i > 0)
            val += ff_nelly_delta_table[get_bits(&s->gb, 5)];
        pval = -pow(2, val/2048) * s->scale_bias;
        for (j = 0; j < ff_nelly_band_sizes_table[i]; j++) {
            *bptr++ = val;
            *pptr++ = pval;
        }

    }

    ff_nelly_get_sample_bits(buf, bits);

    for (i = 0; i < 2; i++) {
        aptr = audio + i * NELLY_BUF_LEN;

        init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8);
        skip_bits(&s->gb, NELLY_HEADER_BITS + i*NELLY_DETAIL_BITS);

        for (j = 0; j < NELLY_FILL_LEN; j++) {
            if (bits[j] <= 0) {
                aptr[j] = M_SQRT1_2*pows[j];
                if (av_random(&s->random_state) & 1)
                    aptr[j] *= -1.0;
            } else {
                v = get_bits(&s->gb, bits[j]);
                aptr[j] = ff_nelly_dequantization_table[(1<<bits[j])-1+v]*pows[j];
            }
        }
        memset(&aptr[NELLY_FILL_LEN], 0,
               (NELLY_BUF_LEN - NELLY_FILL_LEN) * sizeof(float));

        ff_imdct_calc(&s->imdct_ctx, s->imdct_out, aptr);
        /* XXX: overlapping and windowing should be part of a more
           generic imdct function */
        overlap_and_window(s, s->state, aptr, s->imdct_out);
    }
}

static av_cold int decode_init(AVCodecContext * avctx) {
    NellyMoserDecodeContext *s = avctx->priv_data;

    s->avctx = avctx;
    av_random_init(&s->random_state, 0);
    ff_mdct_init(&s->imdct_ctx, 8, 1);

    dsputil_init(&s->dsp, avctx);

    if(s->dsp.float_to_int16 == ff_float_to_int16_c) {
        s->add_bias = 385;
        s->scale_bias = 1.0/(8*32768);
    } else {
        s->add_bias = 0;
        s->scale_bias = 1.0/(1*8);
    }

    /* Generate overlap window */
    if (!ff_sine_128[127])
        ff_sine_window_init(ff_sine_128, 128);

    avctx->sample_fmt = SAMPLE_FMT_S16;
    avctx->channel_layout = CH_LAYOUT_MONO;
    return 0;
}

static int decode_tag(AVCodecContext * avctx,
                      void *data, int *data_size,
                      const uint8_t * buf, int buf_size) {
    NellyMoserDecodeContext *s = avctx->priv_data;
    int data_max = *data_size;
    int blocks, i;
    int16_t* samples;
    *data_size = 0;
    samples = (int16_t*)data;

    if (buf_size < avctx->block_align)
        return buf_size;

    switch (buf_size) {
        case 64:    // 8000Hz
            blocks = 1; break;
        case 128:   // 11025Hz
            blocks = 2; break;
        case 256:   // 22050Hz
            blocks = 4; break;
        case 512:   // 44100Hz
            blocks = 8; break;
        default:
            av_log(avctx, AV_LOG_DEBUG, "Tag size %d.\n", buf_size);
            return buf_size;
    }

    for (i=0 ; i<blocks ; i++) {
        if ((i + 1) * NELLY_SAMPLES * sizeof(int16_t) > data_max)
            return i > 0 ? i * NELLY_BLOCK_LEN : -1;
        nelly_decode_block(s, &buf[i*NELLY_BLOCK_LEN], s->float_buf);
        s->dsp.float_to_int16(&samples[i*NELLY_SAMPLES], s->float_buf, NELLY_SAMPLES);
        *data_size += NELLY_SAMPLES*sizeof(int16_t);
    }

    return buf_size;
}

static av_cold int decode_end(AVCodecContext * avctx) {
    NellyMoserDecodeContext *s = avctx->priv_data;

    ff_mdct_end(&s->imdct_ctx);
    return 0;
}

AVCodec nellymoser_decoder = {
    "nellymoser",
    CODEC_TYPE_AUDIO,
    CODEC_ID_NELLYMOSER,
    sizeof(NellyMoserDecodeContext),
    decode_init,
    NULL,
    decode_end,
    decode_tag,
    .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
};

