/* -*- c-basic-offset: 2 -*-
 * GStreamer
 * Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
 *
 * 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.
 */

/**
 * SECTION:element-speed
 *
 * Plays an audio stream at a different speed (by resampling the audio).
 * 
 * Do not use this element. Either use the 'pitch' element, or do a seek with
 * a non-1.0 rate parameter, this will have the same effect as using the speed
 * element (but relies on the decoder/demuxer to handle this correctly, also
 * requires a fairly up-to-date gst-plugins-base, as of February 2007).
 * 
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 filesrc location=test.ogg ! decodebin ! audioconvert ! speed speed=1.5 ! audioconvert ! audioresample ! autoaudiosink
 * ]| Plays an .ogg file at 1.5x speed.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <string.h>
#include <math.h>
#include <gst/gst.h>
#include <gst/audio/audio.h>

#include "gstspeed.h"

GST_DEBUG_CATEGORY_STATIC (speed_debug);
#define GST_CAT_DEFAULT speed_debug

enum
{
  PROP_0,
  PROP_SPEED
};

/* assumption here: sizeof (gfloat) = 4 */
#define GST_SPEED_AUDIO_CAPS \
  "audio/x-raw, " \
    "format = {" GST_AUDIO_NE (F32) ", " GST_AUDIO_NE (S16) "}, " \
    "rate = (int) [ 1, MAX ], " \
    "channels = (int) [ 1, MAX ]"

static GstStaticPadTemplate gst_speed_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_SPEED_AUDIO_CAPS)
    );

static GstStaticPadTemplate gst_speed_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_SPEED_AUDIO_CAPS)
    );

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

static gboolean speed_parse_caps (GstSpeed * filter, const GstCaps * caps);

static GstFlowReturn speed_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);

static GstStateChangeReturn speed_change_state (GstElement * element,
    GstStateChange transition);
static gboolean speed_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean speed_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

G_DEFINE_TYPE (GstSpeed, gst_speed, GST_TYPE_ELEMENT);

static gboolean
speed_setcaps (GstPad * pad, GstCaps * caps)
{
  GstSpeed *filter;
  gboolean ret;

  filter = GST_SPEED (gst_pad_get_parent (pad));

  ret = speed_parse_caps (filter, caps);

  gst_object_unref (filter);

  return ret;
}

static gboolean
speed_parse_caps (GstSpeed * filter, const GstCaps * caps)
{
  g_return_val_if_fail (filter != NULL, FALSE);
  g_return_val_if_fail (caps != NULL, FALSE);

  if (!gst_audio_info_from_caps (&filter->info, caps))
    return FALSE;


  return TRUE;
}

static gboolean
speed_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstSpeed *filter;
  gboolean ret = FALSE;

  filter = GST_SPEED (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:{
      gdouble rate;
      GstFormat format;
      GstSeekFlags flags;
      GstSeekType start_type, stop_type;
      gint64 start, stop;

      gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
          &stop_type, &stop);
      gst_event_unref (event);

      if (format != GST_FORMAT_TIME) {
        GST_DEBUG_OBJECT (filter, "only support seeks in TIME format");
        break;
      }

      if (start_type != GST_SEEK_TYPE_NONE && start != -1) {
        start *= filter->speed;
      }

      if (stop_type != GST_SEEK_TYPE_NONE && stop != -1) {
        stop *= filter->speed;
      }

      event = gst_event_new_seek (rate, format, flags, start_type, start,
          stop_type, stop);

      GST_LOG ("sending seek event: %" GST_PTR_FORMAT,
          gst_event_get_structure (event));

      ret = gst_pad_send_event (GST_PAD_PEER (filter->sinkpad), event);
      break;
    }
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

static gboolean
gst_speed_convert (GstSpeed * filter, GstFormat src_format, gint64 src_value,
    GstFormat * dest_format, gint64 * dest_value)
{
  gboolean ret = TRUE;
  guint scale = 1;

  if (src_format == *dest_format) {
    *dest_value = src_value;
    return TRUE;
  }

  switch (src_format) {
    case GST_FORMAT_BYTES:
      switch (*dest_format) {
        case GST_FORMAT_DEFAULT:
          if (GST_AUDIO_INFO_BPF (&filter->info) == 0) {
            ret = FALSE;
            break;
          }
          *dest_value = src_value / GST_AUDIO_INFO_BPF (&filter->info);
          break;
        case GST_FORMAT_TIME:
        {
          gint byterate =
              GST_AUDIO_INFO_BPF (&filter->info) *
              GST_AUDIO_INFO_RATE (&filter->info);

          if (byterate == 0) {
            ret = FALSE;
            break;
          }
          *dest_value = src_value * GST_SECOND / byterate;
          break;
        }
        default:
          ret = FALSE;
      }
      break;
    case GST_FORMAT_DEFAULT:
      switch (*dest_format) {
        case GST_FORMAT_BYTES:
          *dest_value = src_value * GST_AUDIO_INFO_BPF (&filter->info);
          break;
        case GST_FORMAT_TIME:
          if (GST_AUDIO_INFO_RATE (&filter->info) == 0) {
            ret = FALSE;
            break;
          }
          *dest_value =
              src_value * GST_SECOND / GST_AUDIO_INFO_RATE (&filter->info);
          break;
        default:
          ret = FALSE;
      }
      break;
    case GST_FORMAT_TIME:
      switch (*dest_format) {
        case GST_FORMAT_BYTES:
          scale = GST_AUDIO_INFO_BPF (&filter->info);
          /* fallthrough */
        case GST_FORMAT_DEFAULT:
          *dest_value =
              src_value * scale * GST_AUDIO_INFO_RATE (&filter->info) /
              GST_SECOND;
          break;
        default:
          ret = FALSE;
      }
      break;
    default:
      ret = FALSE;
  }

  return ret;

}

static gboolean
speed_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean ret = TRUE;
  GstSpeed *filter;

  filter = GST_SPEED (parent);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_POSITION:
    {
      GstFormat format;
      GstFormat rformat = GST_FORMAT_TIME;
      gint64 cur;
      GstFormat conv_format = GST_FORMAT_TIME;

      /* save requested format */
      gst_query_parse_position (query, &format, NULL);

      /* query peer for current position in time */
      gst_query_set_position (query, GST_FORMAT_TIME, -1);

      if (!gst_pad_peer_query_position (filter->sinkpad, rformat, &cur)) {
        GST_LOG_OBJECT (filter, "TIME query on peer pad failed, trying BYTES");
        rformat = GST_FORMAT_BYTES;
        if (!gst_pad_peer_query_position (filter->sinkpad, rformat, &cur)) {
          GST_LOG_OBJECT (filter, "BYTES query on peer pad failed too");
          goto error;
        }
      }

      if (rformat == GST_FORMAT_BYTES)
        GST_LOG_OBJECT (filter,
            "peer pad returned current=%" G_GINT64_FORMAT " bytes", cur);
      else if (rformat == GST_FORMAT_TIME)
        GST_LOG_OBJECT (filter, "peer pad returned time=%" G_GINT64_FORMAT,
            cur);

      /* convert to time format */
      if (!gst_speed_convert (filter, rformat, cur, &conv_format, &cur)) {
        ret = FALSE;
        break;
      }

      /* adjust for speed factor */
      cur /= filter->speed;

      /* convert to time format */
      if (!gst_speed_convert (filter, conv_format, cur, &format, &cur)) {
        ret = FALSE;
        break;
      }
      gst_query_set_position (query, format, cur);

      GST_LOG_OBJECT (filter,
          "position query: we return %" G_GUINT64_FORMAT " (format %u)", cur,
          format);

      break;
    }
    case GST_QUERY_DURATION:
    {
      GstFormat format;
      GstFormat rformat = GST_FORMAT_TIME;
      gint64 end;
      GstFormat conv_format = GST_FORMAT_TIME;

      /* save requested format */
      gst_query_parse_duration (query, &format, NULL);

      /* query peer for total length in time */
      gst_query_set_duration (query, GST_FORMAT_TIME, -1);

      if (!gst_pad_peer_query_duration (filter->sinkpad, rformat, &end)) {
        GST_LOG_OBJECT (filter, "TIME query on peer pad failed, trying BYTES");
        rformat = GST_FORMAT_BYTES;
        if (!gst_pad_peer_query_duration (filter->sinkpad, rformat, &end)) {
          GST_LOG_OBJECT (filter, "BYTES query on peer pad failed too");
          goto error;
        }
      }

      if (rformat == GST_FORMAT_BYTES)
        GST_LOG_OBJECT (filter,
            "peer pad returned total=%" G_GINT64_FORMAT " bytes", end);
      else if (rformat == GST_FORMAT_TIME)
        GST_LOG_OBJECT (filter, "peer pad returned time=%" G_GINT64_FORMAT,
            end);

      /* convert to time format */
      if (!gst_speed_convert (filter, rformat, end, &conv_format, &end)) {
        ret = FALSE;
        break;
      }

      /* adjust for speed factor */
      end /= filter->speed;

      /* convert to time format */
      if (!gst_speed_convert (filter, conv_format, end, &format, &end)) {
        ret = FALSE;
        break;
      }

      gst_query_set_duration (query, format, end);

      GST_LOG_OBJECT (filter,
          "duration query: we return %" G_GUINT64_FORMAT " (format %u)", end,
          format);

      break;
    }
    default:
      ret = FALSE;
      break;
  }

  return ret;

error:

  gst_object_unref (filter);
  GST_DEBUG ("error handling query");
  return FALSE;
}

static void
gst_speed_class_init (GstSpeedClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;

  gobject_class->set_property = speed_set_property;
  gobject_class->get_property = speed_get_property;
  gstelement_class->change_state = speed_change_state;

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SPEED,
      g_param_spec_float ("speed", "speed", "speed",
          0.1, 40.0, 1.0,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (gstelement_class, "Speed",
      "Filter/Effect/Audio",
      "Set speed/pitch on audio/raw streams (resampler)",
      "Andy Wingo <apwingo@eos.ncsu.edu>, "
      "Tim-Philipp Müller <tim@centricular.net>");

  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_speed_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_speed_sink_template);
}

static void
gst_speed_init (GstSpeed * filter)
{
  filter->sinkpad =
      gst_pad_new_from_static_template (&gst_speed_sink_template, "sink");
  gst_pad_set_chain_function (filter->sinkpad, speed_chain);
  gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
  gst_pad_set_event_function (filter->sinkpad, speed_sink_event);
  GST_PAD_SET_PROXY_CAPS (filter->sinkpad);

  filter->srcpad =
      gst_pad_new_from_static_template (&gst_speed_src_template, "src");
  gst_pad_set_query_function (filter->srcpad, speed_src_query);
  gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
  gst_pad_set_event_function (filter->srcpad, speed_src_event);
  GST_PAD_SET_PROXY_CAPS (filter->srcpad);

  filter->offset = 0;
  filter->timestamp = 0;
}

static inline guint
speed_chain_int16 (GstSpeed * filter, GstBuffer * in_buf, GstBuffer * out_buf,
    guint c, guint in_samples)
{
  gint16 *in_data, *out_data;
  gfloat interp, lower, i_float;
  guint i, j;
  GstMapInfo in_info, out_info;

  gst_buffer_map (in_buf, &in_info, GST_MAP_READ);
  gst_buffer_map (out_buf, &out_info, GST_MAP_WRITE);

  in_data = (gint16 *) in_info.data + c;
  out_data = (gint16 *) out_info.data + c;

  lower = in_data[0];
  i_float = 0.5 * (filter->speed - 1.0);
  i = (guint) ceil (i_float);
  j = 0;

  while (i < in_samples) {
    interp = i_float - floor (i_float);

    out_data[j * GST_AUDIO_INFO_CHANNELS (&filter->info)] =
        lower * (1 - interp) +
        in_data[i * GST_AUDIO_INFO_CHANNELS (&filter->info)] * interp;

    lower = in_data[i * GST_AUDIO_INFO_CHANNELS (&filter->info)];

    i_float += filter->speed;
    i = (guint) ceil (i_float);

    ++j;
  }

  gst_buffer_unmap (in_buf, &in_info);
  gst_buffer_unmap (out_buf, &out_info);
  return j;
}

static inline guint
speed_chain_float32 (GstSpeed * filter, GstBuffer * in_buf, GstBuffer * out_buf,
    guint c, guint in_samples)
{
  gfloat *in_data, *out_data;
  gfloat interp, lower, i_float;
  guint i, j;
  GstMapInfo in_info, out_info;

  gst_buffer_map (in_buf, &in_info, GST_MAP_WRITE);
  gst_buffer_map (out_buf, &out_info, GST_MAP_WRITE);

  in_data = (gfloat *) in_info.data + c;
  out_data = (gfloat *) out_info.data + c;

  lower = in_data[0];
  i_float = 0.5 * (filter->speed - 1.0);
  i = (guint) ceil (i_float);
  j = 0;

  while (i < in_samples) {
    interp = i_float - floor (i_float);

    out_data[j * GST_AUDIO_INFO_CHANNELS (&filter->info)] =
        lower * (1 - interp) +
        in_data[i * GST_AUDIO_INFO_CHANNELS (&filter->info)] * interp;

    lower = in_data[i * GST_AUDIO_INFO_CHANNELS (&filter->info)];

    i_float += filter->speed;
    i = (guint) ceil (i_float);

    ++j;
  }
  gst_buffer_unmap (in_buf, &in_info);
  gst_buffer_unmap (out_buf, &out_info);
  return j;
}


static gboolean
speed_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstSpeed *filter = GST_SPEED (parent);
  gboolean ret = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:{
      gdouble rate;
      GstFormat format;
      gint64 start_value, stop_value, base;
      const GstSegment *segment;
      GstSegment seg;

      gst_event_parse_segment (event, &segment);

      rate = segment->rate;
      format = segment->format;
      start_value = segment->start;
      stop_value = segment->stop;
      base = segment->base;

      gst_event_unref (event);

      if (format != GST_FORMAT_TIME) {
        GST_WARNING_OBJECT (filter, "newsegment event not in TIME format!");
        break;
      }

      g_assert (filter->speed > 0);

      if (start_value >= 0)
        start_value /= filter->speed;
      if (stop_value >= 0)
        stop_value /= filter->speed;
      base /= filter->speed;

      /* this would only really be correct if we clipped incoming data */
      filter->timestamp = start_value;

      /* set to NONE so it gets reset later based on the timestamp when we have
       * the samplerate */
      filter->offset = GST_BUFFER_OFFSET_NONE;

      gst_segment_init (&seg, GST_FORMAT_TIME);
      seg.rate = rate;
      seg.start = start_value;
      seg.stop = stop_value;
      seg.time = segment->time;
      ret = gst_pad_push_event (filter->srcpad, gst_event_new_segment (&seg));

      break;
    }
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = speed_setcaps (pad, caps);
      if (!ret) {
        gst_event_unref (event);
        return ret;
      }
    }
      /* Fallthrough so that the caps event gets forwarded */
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }
  return ret;
}

static GstFlowReturn
speed_chain (GstPad * pad, GstObject * parent, GstBuffer * in_buf)
{
  GstBuffer *out_buf;
  GstSpeed *filter = GST_SPEED (parent);
  guint c, in_samples, out_samples, out_size;
  GstFlowReturn flow;
  gsize size;

  if (G_UNLIKELY (filter->offset == GST_BUFFER_OFFSET_NONE)) {
    filter->offset = gst_util_uint64_scale_int (filter->timestamp,
        GST_AUDIO_INFO_RATE (&filter->info), GST_SECOND);
  }

  /* buffersize has to be aligned to a frame */
  out_size = ceil ((gfloat) gst_buffer_get_size (in_buf) / filter->speed);
  out_size = ((out_size + GST_AUDIO_INFO_BPF (&filter->info) - 1) /
      GST_AUDIO_INFO_BPF (&filter->info)) * GST_AUDIO_INFO_BPF (&filter->info);

  out_buf = gst_buffer_new_and_alloc (out_size);

  in_samples = gst_buffer_get_size (in_buf) /
      GST_AUDIO_INFO_BPF (&filter->info);

  out_samples = 0;

  for (c = 0; c < GST_AUDIO_INFO_CHANNELS (&filter->info); ++c) {
    if (GST_AUDIO_INFO_IS_INTEGER (&filter->info))
      out_samples = speed_chain_int16 (filter, in_buf, out_buf, c, in_samples);
    else
      out_samples =
          speed_chain_float32 (filter, in_buf, out_buf, c, in_samples);
  }

  size = out_samples * GST_AUDIO_INFO_BPF (&filter->info);
  gst_buffer_set_size (out_buf, size);

  GST_BUFFER_OFFSET (out_buf) = filter->offset;
  GST_BUFFER_TIMESTAMP (out_buf) = filter->timestamp;

  filter->offset += size / GST_AUDIO_INFO_BPF (&filter->info);
  filter->timestamp = gst_util_uint64_scale_int (filter->offset, GST_SECOND,
      GST_AUDIO_INFO_RATE (&filter->info));

  /* make sure it's at least nominally a perfect stream */
  GST_BUFFER_DURATION (out_buf) =
      filter->timestamp - GST_BUFFER_TIMESTAMP (out_buf);
  flow = gst_pad_push (filter->srcpad, out_buf);

  if (G_UNLIKELY (flow != GST_FLOW_OK))
    GST_DEBUG_OBJECT (filter, "flow: %s", gst_flow_get_name (flow));

  gst_buffer_unref (in_buf);
  return flow;
}

static void
speed_set_property (GObject * object, guint prop_id, const GValue * value,
    GParamSpec * pspec)
{
  GstSpeed *filter = GST_SPEED (object);

  switch (prop_id) {
    case PROP_SPEED:
      filter->speed = g_value_get_float (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

}

static void
speed_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstSpeed *filter = GST_SPEED (object);

  switch (prop_id) {
    case PROP_SPEED:
      g_value_set_float (value, filter->speed);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

}

static GstStateChangeReturn
speed_change_state (GstElement * element, GstStateChange transition)
{
  GstSpeed *speed = GST_SPEED (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      speed->offset = GST_BUFFER_OFFSET_NONE;
      speed->timestamp = 0;
      gst_audio_info_init (&speed->info);
      break;
    default:
      break;
  }

  return GST_ELEMENT_CLASS (gst_speed_parent_class)->change_state (element,
      transition);
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (speed_debug, "speed", 0, "speed element");

  return gst_element_register (plugin, "speed", GST_RANK_NONE, GST_TYPE_SPEED);
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    speed,
    "Set speed/pitch on audio/raw streams (resampler)",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
