/* GStreamer TTA plugin
 * (c) 2004 Arwed v. Merkatz <v.merkatz@gmx.net>
 *
 * based on ttalib
 * (c) 1999-2004 Alexander Djourik <sasha@iszf.irk.ru>
 * 
 * gstttadec.c: raw TTA bitstream decoder
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <gst/gst.h>

#include <math.h>
#include <string.h>

#include "gstttadec.h"
#include "ttadec.h"
#include "filters.h"

#define TTA_BUFFER_SIZE (1024 * 32 * 8)

/* this is from ttadec.h originally */

static const unsigned long bit_mask[] = {
  0x00000000, 0x00000001, 0x00000003, 0x00000007,
  0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
  0xffffffff
};

static const unsigned long bit_shift[] = {
  0x00000001, 0x00000002, 0x00000004, 0x00000008,
  0x00000010, 0x00000020, 0x00000040, 0x00000080,
  0x00000100, 0x00000200, 0x00000400, 0x00000800,
  0x00001000, 0x00002000, 0x00004000, 0x00008000,
  0x00010000, 0x00020000, 0x00040000, 0x00080000,
  0x00100000, 0x00200000, 0x00400000, 0x00800000,
  0x01000000, 0x02000000, 0x04000000, 0x08000000,
  0x10000000, 0x20000000, 0x40000000, 0x80000000,
  0x80000000, 0x80000000, 0x80000000, 0x80000000,
  0x80000000, 0x80000000, 0x80000000, 0x80000000
};

static const unsigned long *shift_16 = bit_shift + 4;

/* Filter signals and args */
enum
{
  LAST_SIGNAL
};

enum
{
  PROP_0
};

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-tta, "
        "width = (int) { 8, 16, 24 }, "
        "channels = (int) { 1, 2 }, " "rate = (int) [ 8000, 96000 ]")
    );

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw-int, "
        "width = (int) { 8, 16, 24 }, "
        "depth = (int) { 8, 16, 24 }, "
        "channels = (int) { 1, 2 }, "
        "rate = (int) [ 8000, 96000 ], "
        "endianness = (int) BYTE_ORDER, " "signed = (boolean) true")
    );

static void gst_tta_dec_class_init (GstTtaDecClass * klass);
static void gst_tta_dec_base_init (GstTtaDecClass * klass);
static void gst_tta_dec_init (GstTtaDec * ttadec);

static GstFlowReturn gst_tta_dec_chain (GstPad * pad, GstBuffer * in);

static GstElementClass *parent = NULL;

static gboolean
gst_tta_dec_setcaps (GstPad * pad, GstCaps * caps)
{
  GstTtaDec *ttadec = GST_TTA_DEC (gst_pad_get_parent (pad));
  GstStructure *structure = gst_caps_get_structure (caps, 0);
  GstCaps *srccaps;
  gint bits, channels;
  gint32 samplerate;

//  if (!gst_caps_is_fixed (caps))
//    return GST_PAD_LINK_DELAYED;

  gst_structure_get_int (structure, "rate", &samplerate);
  ttadec->samplerate = (guint32) samplerate;
  gst_structure_get_int (structure, "channels", &channels);
  ttadec->channels = (guint) channels;
  gst_structure_get_int (structure, "width", &bits);
  ttadec->bytes = bits / 8;

  srccaps = gst_caps_new_simple ("audio/x-raw-int",
      "rate", G_TYPE_INT, ttadec->samplerate,
      "channels", G_TYPE_INT, ttadec->channels,
      "depth", G_TYPE_INT, bits,
      "width", G_TYPE_INT, bits,
      "endianness", G_TYPE_INT, G_BYTE_ORDER,
      "signed", G_TYPE_BOOLEAN, TRUE, NULL);

  if (!gst_pad_set_caps (ttadec->srcpad, srccaps))
    return FALSE;

  ttadec->frame_length = FRAME_TIME * ttadec->samplerate;

  ttadec->tta = g_malloc (ttadec->channels * sizeof (decoder));
  ttadec->cache = g_malloc (ttadec->channels * sizeof (long));

  ttadec->decdata =
      (guchar *) g_malloc (ttadec->channels * ttadec->frame_length *
      ttadec->bytes * sizeof (guchar));

  return TRUE;
}

GType
gst_tta_dec_get_type (void)
{
  static GType plugin_type = 0;

  if (!plugin_type) {
    static const GTypeInfo plugin_info = {
      sizeof (GstTtaDecClass),
      (GBaseInitFunc) gst_tta_dec_base_init,
      NULL,
      (GClassInitFunc) gst_tta_dec_class_init,
      NULL,
      NULL,
      sizeof (GstTtaDec),
      0,
      (GInstanceInitFunc) gst_tta_dec_init,
    };
    plugin_type = g_type_register_static (GST_TYPE_ELEMENT,
        "GstTtaDec", &plugin_info, 0);
  }
  return plugin_type;
}

static void
gst_tta_dec_base_init (GstTtaDecClass * klass)
{

  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_factory));
  gst_element_class_set_static_metadata (element_class, "TTA audio decoder",
      "Codec/Decoder/Audio",
      "Decode TTA audio data", "Arwed v. Merkatz <v.merkatz@gmx.net>");
}

static void
gst_tta_dec_dispose (GObject * object)
{
  GstTtaDec *ttadec = GST_TTA_DEC (object);

  g_free (ttadec->tta);
  g_free (ttadec->decdata);
  g_free (ttadec->tta_buf.buffer);

  G_OBJECT_CLASS (parent)->dispose (object);
}

static void
gst_tta_dec_class_init (GstTtaDecClass * klass)
{
  GObjectClass *gobject_class;

  gobject_class = (GObjectClass *) klass;

  parent = g_type_class_peek_parent (klass);

  gobject_class->dispose = gst_tta_dec_dispose;
}

static void
gst_tta_dec_init (GstTtaDec * ttadec)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (ttadec);

  ttadec->sinkpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "sink"), "sink");
  gst_pad_set_setcaps_function (ttadec->sinkpad, gst_tta_dec_setcaps);

  ttadec->srcpad =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "src"), "src");
  gst_pad_use_fixed_caps (ttadec->srcpad);

  gst_element_add_pad (GST_ELEMENT (ttadec), ttadec->sinkpad);
  gst_element_add_pad (GST_ELEMENT (ttadec), ttadec->srcpad);
  gst_pad_set_chain_function (ttadec->sinkpad, gst_tta_dec_chain);
  ttadec->tta_buf.buffer = (guchar *) g_malloc (TTA_BUFFER_SIZE + 4);
  ttadec->tta_buf.buffer_end = ttadec->tta_buf.buffer + TTA_BUFFER_SIZE;
}

static void
rice_init (adapt * rice, unsigned long k0, unsigned long k1)
{
  rice->k0 = k0;
  rice->k1 = k1;
  rice->sum0 = shift_16[k0];
  rice->sum1 = shift_16[k1];
}

static void
decoder_init (decoder * tta, long nch, long byte_size)
{
  long shift = flt_set[byte_size - 1];
  long i;

  for (i = 0; i < nch; i++) {
    filter_init (&tta[i].fst, shift);
    rice_init (&tta[i].rice, 10, 10);
    tta[i].last = 0;
  }
}

static void
get_binary (tta_buffer * tta_buf, guchar * buffer, unsigned long buffersize,
    unsigned long *value, unsigned long bits)
{
  while (tta_buf->bit_count < bits) {
    if (tta_buf->bitpos == tta_buf->buffer_end) {
      int max =
          TTA_BUFFER_SIZE <=
          buffersize - tta_buf->offset ? TTA_BUFFER_SIZE : buffersize -
          tta_buf->offset;
      memcpy (tta_buf->buffer, buffer + tta_buf->offset, max);
      tta_buf->offset += max;
      tta_buf->bitpos = tta_buf->buffer;
    }

    tta_buf->bit_cache |= *tta_buf->bitpos << tta_buf->bit_count;
    tta_buf->bit_count += 8;
    tta_buf->bitpos++;
  }

  *value = tta_buf->bit_cache & bit_mask[bits];
  tta_buf->bit_cache >>= bits;
  tta_buf->bit_count -= bits;
  tta_buf->bit_cache &= bit_mask[tta_buf->bit_count];
}

static void
get_unary (tta_buffer * tta_buf, guchar * buffer, unsigned long buffersize,
    unsigned long *value)
{
  *value = 0;

  while (!(tta_buf->bit_cache ^ bit_mask[tta_buf->bit_count])) {
    if (tta_buf->bitpos == tta_buf->buffer_end) {
      int max =
          TTA_BUFFER_SIZE <=
          buffersize - tta_buf->offset ? TTA_BUFFER_SIZE : buffersize -
          tta_buf->offset;
      memcpy (tta_buf->buffer, buffer + tta_buf->offset, max);
      tta_buf->offset += max;
      tta_buf->bitpos = tta_buf->buffer;
    }

    *value += tta_buf->bit_count;
    tta_buf->bit_cache = *tta_buf->bitpos++;
    tta_buf->bit_count = 8;
  }

  while (tta_buf->bit_cache & 1) {
    (*value)++;
    tta_buf->bit_cache >>= 1;
    tta_buf->bit_count--;
  }

  tta_buf->bit_cache >>= 1;
  tta_buf->bit_count--;
}

static GstFlowReturn
gst_tta_dec_chain (GstPad * pad, GstBuffer * in)
{
  GstTtaDec *ttadec;
  GstBuffer *outbuf, *buf = GST_BUFFER (in);
  guchar *data, *p;
  decoder *dec;
  unsigned long outsize;
  unsigned long size;
  guint32 frame_samples;
  long res;
  long *prev;

  ttadec = GST_TTA_DEC (GST_OBJECT_PARENT (pad));

  data = GST_BUFFER_DATA (buf);
  size = GST_BUFFER_SIZE (buf);

  ttadec->tta_buf.bit_count = 0;
  ttadec->tta_buf.bit_cache = 0;
  ttadec->tta_buf.bitpos = ttadec->tta_buf.buffer_end;
  ttadec->tta_buf.offset = 0;
  decoder_init (ttadec->tta, ttadec->channels, ttadec->bytes);

  if (GST_BUFFER_DURATION_IS_VALID (buf)) {
    frame_samples =
        ceil ((gdouble) (GST_BUFFER_DURATION (buf) * ttadec->samplerate) /
        (gdouble) GST_SECOND);
  } else {
    frame_samples = ttadec->samplerate * FRAME_TIME;
  }
  outsize = ttadec->channels * frame_samples * ttadec->bytes;

  dec = ttadec->tta;
  p = ttadec->decdata;
  prev = ttadec->cache;
  for (res = 0;
      p < ttadec->decdata + frame_samples * ttadec->channels * ttadec->bytes;) {
    unsigned long unary, binary, depth, k;
    long value, temp_value;
    fltst *fst = &dec->fst;
    adapt *rice = &dec->rice;
    long *last = &dec->last;

    // decode Rice unsigned
    get_unary (&ttadec->tta_buf, data, size, &unary);

    switch (unary) {
      case 0:
        depth = 0;
        k = rice->k0;
        break;
      default:
        depth = 1;
        k = rice->k1;
        unary--;
    }

    if (k) {
      get_binary (&ttadec->tta_buf, data, size, &binary, k);
      value = (unary << k) + binary;
    } else
      value = unary;

    switch (depth) {
      case 1:
        rice->sum1 += value - (rice->sum1 >> 4);
        if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1])
          rice->k1--;
        else if (rice->sum1 > shift_16[rice->k1 + 1])
          rice->k1++;
        value += bit_shift[rice->k0];
      default:
        rice->sum0 += value - (rice->sum0 >> 4);
        if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0])
          rice->k0--;
        else if (rice->sum0 > shift_16[rice->k0 + 1])
          rice->k0++;
    }

    /* this only uses a temporary variable to silence a gcc warning */
    temp_value = DEC (value);
    value = temp_value;

    // decompress stage 1: adaptive hybrid filter
    hybrid_filter (fst, &value);

    // decompress stage 2: fixed order 1 prediction
    switch (ttadec->bytes) {
      case 1:
        value += PREDICTOR1 (*last, 4);
        break;                  // bps 8
      case 2:
        value += PREDICTOR1 (*last, 5);
        break;                  // bps 16
      case 3:
        value += PREDICTOR1 (*last, 5);
        break;                  // bps 24
      case 4:
        value += *last;
        break;                  // bps 32
    }
    *last = value;

    if (dec < ttadec->tta + ttadec->channels - 1) {
      *prev++ = value;
      dec++;
    } else {
      *prev = value;
      if (ttadec->channels > 1) {
        long *r = prev - 1;

        for (*prev += *r / 2; r >= ttadec->cache; r--)
          *r = *(r + 1) - *r;
        for (r = ttadec->cache; r < prev; r++)
          WRITE_BUFFER (r, ttadec->bytes, p);
      }
      WRITE_BUFFER (prev, ttadec->bytes, p);
      prev = ttadec->cache;
      res++;
      dec = ttadec->tta;
    }
  }

  outbuf = gst_buffer_new_and_alloc (outsize);
  memcpy (GST_BUFFER_DATA (outbuf), ttadec->decdata, outsize);
  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (ttadec->srcpad));
  return gst_pad_push (ttadec->srcpad, outbuf);
}

gboolean
gst_tta_dec_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "ttadec",
      GST_RANK_NONE, GST_TYPE_TTA_DEC);
}
