/*
 * RoQ audio encoder
 *
 * Copyright (c) 2005 Eric Lasota
 *    Based on RoQ specs (c)2001 Tim Ferguson
 *
 * 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 "avcodec.h"
#include "bytestream.h"

#define ROQ_FIRST_FRAME_SIZE     (735*8)
#define ROQ_FRAME_SIZE           735


#define MAX_DPCM (127*127)
static unsigned char dpcmValues[MAX_DPCM];


typedef struct
{
    short lastSample[2];
} ROQDPCMContext;

static av_cold void roq_dpcm_table_init(void)
{
    int i;

    /* Create a table of quick DPCM values */
    for (i=0; i<MAX_DPCM; i++) {
        int s= ff_sqrt(i);
        int mid= s*s + s;
        dpcmValues[i]= s + (i>mid);
    }
}

static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx)
{
    ROQDPCMContext *context = avctx->priv_data;

    if (avctx->channels > 2) {
        av_log(avctx, AV_LOG_ERROR, "Audio must be mono or stereo\n");
        return -1;
    }
    if (avctx->sample_rate != 22050) {
        av_log(avctx, AV_LOG_ERROR, "Audio must be 22050 Hz\n");
        return -1;
    }
    if (avctx->sample_fmt != SAMPLE_FMT_S16) {
        av_log(avctx, AV_LOG_ERROR, "Audio must be signed 16-bit\n");
        return -1;
    }

    roq_dpcm_table_init();

    avctx->frame_size = ROQ_FIRST_FRAME_SIZE;

    context->lastSample[0] = context->lastSample[1] = 0;

    avctx->coded_frame= avcodec_alloc_frame();
    avctx->coded_frame->key_frame= 1;

    return 0;
}

static unsigned char dpcm_predict(short *previous, short current)
{
    int diff;
    int negative;
    int result;
    int predicted;

    diff = current - *previous;

    negative = diff<0;
    diff = FFABS(diff);

    if (diff >= MAX_DPCM)
        result = 127;
    else
        result = dpcmValues[diff];

    /* See if this overflows */
 retry:
    diff = result*result;
    if (negative)
        diff = -diff;
    predicted = *previous + diff;

    /* If it overflows, back off a step */
    if (predicted > 32767 || predicted < -32768) {
        result--;
        goto retry;
    }

    /* Add the sign bit */
    result |= negative << 7;   //if (negative) result |= 128;

    *previous = predicted;

    return result;
}

static int roq_dpcm_encode_frame(AVCodecContext *avctx,
                unsigned char *frame, int buf_size, void *data)
{
    int i, samples, stereo, ch;
    short *in;
    unsigned char *out;

    ROQDPCMContext *context = avctx->priv_data;

    stereo = (avctx->channels == 2);

    if (stereo) {
        context->lastSample[0] &= 0xFF00;
        context->lastSample[1] &= 0xFF00;
    }

    out = frame;
    in = data;

    bytestream_put_byte(&out, stereo ? 0x21 : 0x20);
    bytestream_put_byte(&out, 0x10);
    bytestream_put_le32(&out, avctx->frame_size*avctx->channels);

    if (stereo) {
        bytestream_put_byte(&out, (context->lastSample[1])>>8);
        bytestream_put_byte(&out, (context->lastSample[0])>>8);
    } else
        bytestream_put_le16(&out, context->lastSample[0]);

    /* Write the actual samples */
    samples = avctx->frame_size;
    for (i=0; i<samples; i++)
        for (ch=0; ch<avctx->channels; ch++)
            *out++ = dpcm_predict(&context->lastSample[ch], *in++);

    /* Use smaller frames from now on */
    avctx->frame_size = ROQ_FRAME_SIZE;

    /* Return the result size */
    return out - frame;
}

static av_cold int roq_dpcm_encode_close(AVCodecContext *avctx)
{
    av_freep(&avctx->coded_frame);

    return 0;
}

AVCodec roq_dpcm_encoder = {
    "roq_dpcm",
    CODEC_TYPE_AUDIO,
    CODEC_ID_ROQ_DPCM,
    sizeof(ROQDPCMContext),
    roq_dpcm_encode_init,
    roq_dpcm_encode_frame,
    roq_dpcm_encode_close,
    NULL,
    .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
    .long_name = NULL_IF_CONFIG_SMALL("id RoQ DPCM"),
};
