/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) 2003,2004 David A. Schleef <ds@schleef.org>
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
/* Element-Checklist-Version: 5 */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <math.h>

/*#define DEBUG_ENABLED */
#include "gstaudioresample.h"
#include <gst/audio/audio.h>

GST_DEBUG_CATEGORY_STATIC (audioresample_debug);
#define GST_CAT_DEFAULT audioresample_debug

/* elementfactory information */
static const GstElementDetails gst_audioresample_details =
GST_ELEMENT_DETAILS ("Audio scaler",
    "Filter/Converter/Audio",
    "Resample audio",
    "David Schleef <ds@schleef.org>");

/* Audioresample signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  ARG_0,
  ARG_FILTERLEN
};

#define SUPPORTED_CAPS \
  GST_STATIC_CAPS (\
    "audio/x-raw-int, " \
      "rate = (int) [ 1, MAX ], " \
      "channels = (int) [ 1, MAX ], " \
      "endianness = (int) BYTE_ORDER, " \
      "width = (int) 16, " \
      "depth = (int) 16, " \
      "signed = (boolean) true"
#if 0
    /* disabled because it segfaults */
"audio/x-raw-float, "
    "rate = (int) [ 1, MAX ], "
    "channels = (int) [ 1, MAX ], "
    "endianness = (int) BYTE_ORDER, " "width = (int) 32"
#endif
    )

     static GstStaticPadTemplate gst_audioresample_sink_template =
         GST_STATIC_PAD_TEMPLATE ("sink",
         GST_PAD_SINK, GST_PAD_ALWAYS, SUPPORTED_CAPS);

     static GstStaticPadTemplate gst_audioresample_src_template =
         GST_STATIC_PAD_TEMPLATE ("src",
         GST_PAD_SRC, GST_PAD_ALWAYS, SUPPORTED_CAPS);

     static void gst_audioresample_base_init (gpointer g_class);
     static void gst_audioresample_class_init (AudioresampleClass * klass);
     static void gst_audioresample_init (Audioresample * audioresample);
     static void gst_audioresample_dispose (GObject * object);

     static void gst_audioresample_chain (GstPad * pad, GstData * _data);

     static void gst_audioresample_set_property (GObject * object,
         guint prop_id, const GValue * value, GParamSpec * pspec);
     static void gst_audioresample_get_property (GObject * object,
         guint prop_id, GValue * value, GParamSpec * pspec);

     static GstElementClass *parent_class = NULL;

/*static guint gst_audioresample_signals[LAST_SIGNAL] = { 0 }; */

     GType audioresample_get_type (void)
     {
       static GType audioresample_type = 0;

       if (!audioresample_type)
       {
         static const GTypeInfo audioresample_info = {
         sizeof (AudioresampleClass),
               gst_audioresample_base_init,
               NULL,
               (GClassInitFunc) gst_audioresample_class_init,
               NULL,
               NULL,
               sizeof (Audioresample), 0,
               (GInstanceInitFunc) gst_audioresample_init,};

         audioresample_type =
             g_type_register_static (GST_TYPE_ELEMENT, "Audioresample",
             &audioresample_info, 0);
       }
       return audioresample_type;
     }

static void gst_audioresample_base_init (gpointer g_class)
{
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_audioresample_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_audioresample_sink_template));

  gst_element_class_set_details (gstelement_class, &gst_audioresample_details);
}

static void gst_audioresample_class_init (AudioresampleClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  gobject_class->set_property = gst_audioresample_set_property;
  gobject_class->get_property = gst_audioresample_get_property;
  gobject_class->dispose = gst_audioresample_dispose;

  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILTERLEN,
      g_param_spec_int ("filter_length", "filter_length", "filter_length",
          0, G_MAXINT, 16, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));

  parent_class = g_type_class_peek_parent (klass);

  GST_DEBUG_CATEGORY_INIT (audioresample_debug, "audioresample", 0,
      "audioresample element");
}

static void gst_audioresample_expand_caps (GstCaps * caps)
{
  gint i;

  for (i = 0; i < gst_caps_get_size (caps); i++) {
    GstStructure *structure = gst_caps_get_structure (caps, i);
    const GValue *value;

    value = gst_structure_get_value (structure, "rate");
    if (value == NULL) {
      GST_ERROR ("caps structure doesn't have required rate field");
      return;
    }

    gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, 0);
  }
}

static GstCaps *gst_audioresample_getcaps (GstPad * pad)
{
  Audioresample *audioresample;
  GstCaps *caps;
  GstPad *otherpad;

  audioresample = GST_AUDIORESAMPLE (gst_pad_get_parent (pad));

  otherpad = (pad == audioresample->srcpad) ? audioresample->sinkpad :
      audioresample->srcpad;
  caps = gst_pad_get_allowed_caps (otherpad);

  gst_audioresample_expand_caps (caps);

  return caps;
}

static GstCaps *gst_audioresample_fixate (GstPad * pad, const GstCaps * caps)
{
  Audioresample *audioresample;
  GstPad *otherpad;
  int rate;
  GstCaps *copy;
  GstStructure *structure;

    audioresample = GST_AUDIORESAMPLE (gst_pad_get_parent (pad));

  if (pad == audioresample->srcpad) {
    otherpad = audioresample->sinkpad;
    rate = audioresample->i_rate;
  } else
  {
    otherpad = audioresample->srcpad;
    rate = audioresample->o_rate;
  }
  if (!GST_PAD_IS_NEGOTIATING (otherpad))
    return NULL;
  if (gst_caps_get_size (caps) > 1)
    return NULL;

  copy = gst_caps_copy (caps);
  structure = gst_caps_get_structure (copy, 0);
  if (rate) {
    if (gst_structure_fixate_field_nearest_int (structure, "rate", rate)) {
      return copy;
    }
  }
  gst_caps_free (copy);
  return NULL;
}

static GstPadLinkReturn gst_audioresample_link (GstPad * pad,
    const GstCaps * caps)
{
  Audioresample *audioresample;
  GstStructure *structure;
  int rate;
  int channels;
  gboolean ret;
  GstPad *otherpad;

    audioresample = GST_AUDIORESAMPLE (gst_pad_get_parent (pad));

    otherpad = (pad == audioresample->srcpad) ? audioresample->sinkpad :
      audioresample->srcpad;

    structure = gst_caps_get_structure (caps, 0);
    ret = gst_structure_get_int (structure, "rate", &rate);
    ret &= gst_structure_get_int (structure, "channels", &channels);
  if (!ret)
  {
    return GST_PAD_LINK_REFUSED;
  }

  if (gst_pad_is_negotiated (otherpad))
  {
    GstCaps *othercaps = gst_caps_copy (caps);
    int otherrate;
    GstPadLinkReturn linkret;

    if (pad == audioresample->srcpad) {
      otherrate = audioresample->i_rate;
    } else {
      otherrate = audioresample->o_rate;
    }
    gst_caps_set_simple (othercaps, "rate", G_TYPE_INT, otherrate, NULL);
    linkret = gst_pad_try_set_caps (otherpad, othercaps);
    if (GST_PAD_LINK_FAILED (linkret)) {
      return GST_PAD_LINK_REFUSED;
    }

  }

  audioresample->channels = channels;
  resample_set_n_channels (audioresample->resample, audioresample->channels);
  if (pad == audioresample->srcpad) {
    audioresample->o_rate = rate;
    resample_set_output_rate (audioresample->resample, audioresample->o_rate);
    GST_DEBUG ("set o_rate to %d", rate);
  } else {
    audioresample->i_rate = rate;
    resample_set_input_rate (audioresample->resample, audioresample->i_rate);
    GST_DEBUG ("set i_rate to %d", rate);
  }

  return GST_PAD_LINK_OK;
}

static void gst_audioresample_init (Audioresample * audioresample)
{
  ResampleState *r;

  audioresample->sinkpad =
      gst_pad_new_from_static_template (&gst_audioresample_sink_template,
      "sink");
  gst_element_add_pad (GST_ELEMENT (audioresample), audioresample->sinkpad);
  gst_pad_set_chain_function (audioresample->sinkpad, gst_audioresample_chain);
  gst_pad_set_link_function (audioresample->sinkpad, gst_audioresample_link);
  gst_pad_set_getcaps_function (audioresample->sinkpad,
      gst_audioresample_getcaps);
  gst_pad_set_fixate_function (audioresample->sinkpad,
      gst_audioresample_fixate);

  audioresample->srcpad =
      gst_pad_new_from_static_template (&gst_audioresample_src_template, "src");

  gst_element_add_pad (GST_ELEMENT (audioresample), audioresample->srcpad);
  gst_pad_set_link_function (audioresample->srcpad, gst_audioresample_link);
  gst_pad_set_getcaps_function (audioresample->srcpad,
      gst_audioresample_getcaps);
  gst_pad_set_fixate_function (audioresample->srcpad, gst_audioresample_fixate);

  r = resample_new ();
  audioresample->resample = r;

  resample_set_filter_length (r, 64);
  resample_set_format (r, RESAMPLE_FORMAT_S16);
}

static void gst_audioresample_dispose (GObject * object)
{
  Audioresample *audioresample = GST_AUDIORESAMPLE (object);

  if (audioresample->resample) {
    resample_free (audioresample->resample);
  }

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

static void gst_audioresample_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  Audioresample *audioresample;
  ResampleState *r;
  guchar *data;
  gulong size;
  int outsize;
  GstBuffer *outbuf;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  audioresample = GST_AUDIORESAMPLE (gst_pad_get_parent (pad));

  if (!GST_IS_BUFFER (_data)) {
    gst_pad_push (audioresample->srcpad, _data);
    return;
  }

  if (audioresample->passthru) {
    gst_pad_push (audioresample->srcpad, GST_DATA (buf));
    return;
  }

  r = audioresample->resample;

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

  GST_DEBUG ("got buffer of %ld bytes", size);

  resample_add_input_data (r, data, size, (ResampleCallback) gst_data_unref,
      buf);

  outsize = resample_get_output_size (r);
  /* FIXME this is audioresample being dumb.  dunno why */
  if (outsize == 0) {
    GST_ERROR ("overriding outbuf size");
    outsize = size;
  }
  outbuf = gst_buffer_new_and_alloc (outsize);

  outsize = resample_get_output_data (r, GST_BUFFER_DATA (outbuf), outsize);
  GST_BUFFER_SIZE (outbuf) = outsize;

  GST_BUFFER_TIMESTAMP (outbuf) =
      audioresample->offset * GST_SECOND / audioresample->o_rate;
  audioresample->offset += outsize / sizeof (gint16) / audioresample->channels;

  gst_pad_push (audioresample->srcpad, GST_DATA (outbuf));
}

static void
    gst_audioresample_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  Audioresample *audioresample;

    g_return_if_fail (GST_IS_AUDIORESAMPLE (object));
    audioresample = GST_AUDIORESAMPLE (object);

  switch (prop_id) {
    case ARG_FILTERLEN:
      audioresample->filter_length = g_value_get_int (value);
      GST_DEBUG_OBJECT (GST_ELEMENT (audioresample), "new filter length %d\n",
          audioresample->filter_length);
      resample_set_filter_length (audioresample->resample,
          audioresample->filter_length);
      break;
      default:G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
    gst_audioresample_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  Audioresample *audioresample;

  g_return_if_fail (GST_IS_AUDIORESAMPLE (object));
  audioresample = GST_AUDIORESAMPLE (object);

  switch (prop_id) {
    case ARG_FILTERLEN:
      g_value_set_int (value, audioresample->filter_length);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static gboolean plugin_init (GstPlugin * plugin)
{
  resample_init ();

  if (!gst_element_register (plugin, "audioresample", GST_RANK_PRIMARY,
          GST_TYPE_AUDIORESAMPLE)) {
    return FALSE;
  }

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    "audioresample",
    "Resamples audio", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
    GST_PACKAGE_ORIGIN)
