/* GStreamer pitch controller element
 * Copyright (C) 2006 Wouter Paesen <wouter@blue-gate.be>
 *
 * This library 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.
 *
 * 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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
 *
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/* FIXME: workaround for SoundTouch.h of version 1.3.1 defining those
 * variables while it shouldn't. */
#undef VERSION
#undef PACKAGE_VERSION
#undef PACKAGE_TARNAME
#undef PACKAGE_STRING
#undef PACKAGE_NAME
#undef PACKAGE_BUGREPORT
#undef PACKAGE

#include <soundtouch/SoundTouch.h>

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

#include "gstpitch.hh"
#include <math.h>

GST_DEBUG_CATEGORY_STATIC (pitch_debug);
#define GST_CAT_DEFAULT pitch_debug

#define GST_PITCH_GET_PRIVATE(o) (o->priv)
struct _GstPitchPrivate
{
  gfloat stream_time_ratio;

  GstEvent *pending_segment;

    soundtouch::SoundTouch * st;
};

enum
{
  ARG_0,
  ARG_OUT_RATE,
  ARG_RATE,
  ARG_TEMPO,
  ARG_PITCH
};

/* For soundtouch 1.4 */
#if defined(INTEGER_SAMPLES)
#define SOUNDTOUCH_INTEGER_SAMPLES 1
#elif defined(FLOAT_SAMPLES)
#define SOUNDTOUCH_FLOAT_SAMPLES 1
#endif

#if defined(SOUNDTOUCH_FLOAT_SAMPLES)
  #define SUPPORTED_CAPS \
    "audio/x-raw, " \
      "format = (string) " GST_AUDIO_NE (F32) ", " \
      "rate = (int) [ 8000, MAX ], " \
      "channels = (int) [ 1, 2 ]"
#elif defined(SOUNDTOUCH_INTEGER_SAMPLES)
  #define SUPPORTED_CAPS \
    "audio/x-raw, " \
      "format = (string) " GST_AUDIO_NE (S16) ", " \
      "rate = (int) [ 8000, MAX ], " \
      "channels = (int) [ 1, 2 ]"
#else
#error "Only integer or float samples are supported"
#endif

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

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

static void gst_pitch_dispose (GObject * object);
static void gst_pitch_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_pitch_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);


static gboolean gst_pitch_setcaps (GstPitch * pitch, GstCaps * caps);
static GstFlowReturn gst_pitch_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static GstStateChangeReturn gst_pitch_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_pitch_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_pitch_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static gboolean gst_pitch_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);

#define gst_pitch_parent_class parent_class
G_DEFINE_TYPE (GstPitch, gst_pitch, GST_TYPE_ELEMENT);

static void
gst_pitch_class_init (GstPitchClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;

  gobject_class = G_OBJECT_CLASS (klass);
  element_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (pitch_debug, "pitch", 0,
      "audio pitch control element");

  g_type_class_add_private (gobject_class, sizeof (GstPitchPrivate));

  gobject_class->set_property = gst_pitch_set_property;
  gobject_class->get_property = gst_pitch_get_property;
  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pitch_dispose);

  g_object_class_install_property (gobject_class, ARG_PITCH,
      g_param_spec_float ("pitch", "Pitch",
          "Audio stream pitch", 0.1, 10.0, 1.0,
          (GParamFlags) (G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
              G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, ARG_TEMPO,
      g_param_spec_float ("tempo", "Tempo",
          "Audio stream tempo", 0.1, 10.0, 1.0,
          (GParamFlags) (G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
              G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, ARG_RATE,
      g_param_spec_float ("rate", "Rate",
          "Audio stream rate", 0.1, 10.0, 1.0,
          (GParamFlags) (G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
              G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, ARG_OUT_RATE,
      g_param_spec_float ("output-rate", "Output Rate",
          "Output rate on downstream segment events", 0.1, 10.0, 1.0,
          (GParamFlags) (G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
              G_PARAM_STATIC_STRINGS)));

  element_class->change_state = GST_DEBUG_FUNCPTR (gst_pitch_change_state);

  gst_element_class_add_static_pad_template (element_class, &gst_pitch_src_template);
  gst_element_class_add_static_pad_template (element_class, &gst_pitch_sink_template);

  gst_element_class_set_static_metadata (element_class, "Pitch controller",
      "Filter/Effect/Audio", "Control the pitch of an audio stream",
      "Wouter Paesen <wouter@blue-gate.be>");
}

static void
gst_pitch_init (GstPitch * pitch)
{
  pitch->priv =
      G_TYPE_INSTANCE_GET_PRIVATE ((pitch), GST_TYPE_PITCH, GstPitchPrivate);

  pitch->sinkpad =
      gst_pad_new_from_static_template (&gst_pitch_sink_template, "sink");
  gst_pad_set_chain_function (pitch->sinkpad,
      GST_DEBUG_FUNCPTR (gst_pitch_chain));
  gst_pad_set_event_function (pitch->sinkpad,
      GST_DEBUG_FUNCPTR (gst_pitch_sink_event));
  GST_PAD_SET_PROXY_CAPS (pitch->sinkpad);
  gst_element_add_pad (GST_ELEMENT (pitch), pitch->sinkpad);

  pitch->srcpad =
      gst_pad_new_from_static_template (&gst_pitch_src_template, "src");
  gst_pad_set_event_function (pitch->srcpad,
      GST_DEBUG_FUNCPTR (gst_pitch_src_event));
  gst_pad_set_query_function (pitch->srcpad,
      GST_DEBUG_FUNCPTR (gst_pitch_src_query));
  GST_PAD_SET_PROXY_CAPS (pitch->sinkpad);
  gst_element_add_pad (GST_ELEMENT (pitch), pitch->srcpad);

  pitch->priv->st = new soundtouch::SoundTouch ();

  pitch->tempo = 1.0;
  pitch->rate = 1.0;
  pitch->out_seg_rate = 1.0;
  pitch->seg_arate = 1.0;
  pitch->pitch = 1.0;
  pitch->next_buffer_time = GST_CLOCK_TIME_NONE;
  pitch->next_buffer_offset = 0;

  pitch->priv->st->setRate (pitch->rate);
  pitch->priv->st->setTempo (pitch->tempo * pitch->seg_arate);
  pitch->priv->st->setPitch (pitch->pitch);

  pitch->priv->stream_time_ratio = 1.0;
  pitch->min_latency = pitch->max_latency = 0;
}


static void
gst_pitch_dispose (GObject * object)
{
  GstPitch *pitch = GST_PITCH (object);

  if (pitch->priv->st) {
    delete pitch->priv->st;

    pitch->priv->st = NULL;
  }

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

static void
gst_pitch_update_duration (GstPitch * pitch)
{
  GstMessage *m;

  m = gst_message_new_duration_changed (GST_OBJECT (pitch));
  gst_element_post_message (GST_ELEMENT (pitch), m);
}

static void
gst_pitch_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstPitch *pitch = GST_PITCH (object);

  GST_OBJECT_LOCK (pitch);
  switch (prop_id) {
    case ARG_TEMPO:
      pitch->tempo = g_value_get_float (value);
      pitch->priv->stream_time_ratio =
          pitch->tempo * pitch->rate * pitch->seg_arate;
      pitch->priv->st->setTempo (pitch->tempo * pitch->seg_arate);
      GST_OBJECT_UNLOCK (pitch);
      gst_pitch_update_duration (pitch);
      break;
    case ARG_RATE:
      pitch->rate = g_value_get_float (value);
      pitch->priv->stream_time_ratio =
          pitch->tempo * pitch->rate * pitch->seg_arate;
      pitch->priv->st->setRate (pitch->rate);
      GST_OBJECT_UNLOCK (pitch);
      gst_pitch_update_duration (pitch);
      break;
    case ARG_OUT_RATE:
      /* Has no effect until the next input segment */
      pitch->out_seg_rate = g_value_get_float (value);
      GST_OBJECT_UNLOCK (pitch);
      break;
    case ARG_PITCH:
      pitch->pitch = g_value_get_float (value);
      pitch->priv->st->setPitch (pitch->pitch);
      GST_OBJECT_UNLOCK (pitch);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      GST_OBJECT_UNLOCK (pitch);
      break;
  }
}

static void
gst_pitch_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstPitch *pitch = GST_PITCH (object);

  GST_OBJECT_LOCK (pitch);
  switch (prop_id) {
    case ARG_TEMPO:
      g_value_set_float (value, pitch->tempo);
      break;
    case ARG_RATE:
      g_value_set_float (value, pitch->rate);
      break;
    case ARG_OUT_RATE:
      g_value_set_float (value, pitch->out_seg_rate);
      break;
    case ARG_PITCH:
      g_value_set_float (value, pitch->pitch);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  GST_OBJECT_UNLOCK (pitch);
}

static gboolean
gst_pitch_setcaps (GstPitch * pitch, GstCaps * caps)
{
  GstPitchPrivate *priv;

  priv = GST_PITCH_GET_PRIVATE (pitch);

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

  GST_OBJECT_LOCK (pitch);

  /* notify the soundtouch instance of this change */
  priv->st->setSampleRate (pitch->info.rate);
  priv->st->setChannels (pitch->info.channels);

  GST_OBJECT_UNLOCK (pitch);

  return TRUE;
}

/* send a buffer out */
static GstFlowReturn
gst_pitch_forward_buffer (GstPitch * pitch, GstBuffer * buffer)
{
  gint samples;

  GST_BUFFER_TIMESTAMP (buffer) = pitch->next_buffer_time;
  pitch->next_buffer_time += GST_BUFFER_DURATION (buffer);

  samples = GST_BUFFER_OFFSET (buffer);
  GST_BUFFER_OFFSET (buffer) = pitch->next_buffer_offset;
  pitch->next_buffer_offset += samples;
  GST_BUFFER_OFFSET_END (buffer) = pitch->next_buffer_offset;

  GST_LOG ("pushing buffer [%" GST_TIME_FORMAT "]-[%" GST_TIME_FORMAT
      "] (%d samples)", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (pitch->next_buffer_time), samples);

  return gst_pad_push (pitch->srcpad, buffer);
}

/* extract a buffer from soundtouch */
static GstBuffer *
gst_pitch_prepare_buffer (GstPitch * pitch)
{
  GstPitchPrivate *priv;
  guint samples;
  GstBuffer *buffer;
  GstMapInfo info;

  priv = GST_PITCH_GET_PRIVATE (pitch);

  GST_LOG_OBJECT (pitch, "preparing buffer");

  samples = pitch->priv->st->numSamples ();
  if (samples == 0)
    return NULL;

  buffer = gst_buffer_new_and_alloc (samples * pitch->info.bpf);

  gst_buffer_map (buffer, &info, (GstMapFlags) GST_MAP_READWRITE);
  samples = priv->st->receiveSamples ((soundtouch::SAMPLETYPE *) info.data, samples);
  gst_buffer_unmap (buffer, &info);

  if (samples <= 0) {
    gst_buffer_unref (buffer);
    return NULL;
  }

  GST_BUFFER_DURATION (buffer) =
      gst_util_uint64_scale (samples, GST_SECOND, pitch->info.rate);
  /* temporary store samples here, to avoid having to recalculate this */
  GST_BUFFER_OFFSET (buffer) = (gint64) samples;

  return buffer;
}

/* process the last samples, in a later stage we should make sure no more
 * samples are sent out here as strictly necessary, because soundtouch could
 * append zero samples, which could disturb looping.  */
static GstFlowReturn
gst_pitch_flush_buffer (GstPitch * pitch, gboolean send)
{
  GstBuffer *buffer;
  
  if (pitch->priv->st->numUnprocessedSamples() != 0) {
    GST_DEBUG_OBJECT (pitch, "flushing buffer");
    pitch->priv->st->flush ();   
  }

  if (!send)
    return GST_FLOW_OK;

  buffer = gst_pitch_prepare_buffer (pitch);

  if (!buffer)
    return GST_FLOW_OK;

  return gst_pitch_forward_buffer (pitch, buffer);
}

static gboolean
gst_pitch_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstPitch *pitch;
  gboolean res;

  pitch = GST_PITCH (parent);

  GST_DEBUG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:{
      /* transform the event upstream, according to the playback rate */
      gdouble rate;
      GstFormat format;
      GstSeekFlags flags;
      GstSeekType cur_type, stop_type;
      gint64 cur, stop;
      gfloat stream_time_ratio;
      guint32 seqnum;

      GST_OBJECT_LOCK (pitch);
      stream_time_ratio = pitch->priv->stream_time_ratio;
      GST_OBJECT_UNLOCK (pitch);

      gst_event_parse_seek (event, &rate, &format, &flags,
          &cur_type, &cur, &stop_type, &stop);

      seqnum = gst_event_get_seqnum (event);

      gst_event_unref (event);

      if (format == GST_FORMAT_TIME || format == GST_FORMAT_DEFAULT) {
        cur = (gint64) (cur * stream_time_ratio);
        if (stop != -1)
          stop = (gint64) (stop * stream_time_ratio);

        event = gst_event_new_seek (rate, format, flags,
            cur_type, cur, stop_type, stop);
        gst_event_set_seqnum (event, seqnum);
        res = gst_pad_event_default (pad, parent, event);
      } else {
        GST_WARNING_OBJECT (pitch,
            "Seeking only supported in TIME or DEFAULT format");
        res = FALSE;
      }
      break;
    }
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }
  return res;
}

/* generic convert function based on caps, no rate 
 * used here 
 */
static gboolean
gst_pitch_convert (GstPitch * pitch,
    GstFormat src_format, gint64 src_value,
    GstFormat * dst_format, gint64 * dst_value)
{
  gboolean res = TRUE;
  guint sample_size;
  gint samplerate;

  g_return_val_if_fail (dst_format && dst_value, FALSE);

  GST_OBJECT_LOCK (pitch);
  sample_size = pitch->info.bpf;
  samplerate = pitch->info.rate;
  GST_OBJECT_UNLOCK (pitch);

  if (sample_size == 0 || samplerate == 0) {
    return FALSE;
  }

  if (src_format == *dst_format || src_value == -1) {
    *dst_value = src_value;
    return TRUE;
  }

  switch (src_format) {
    case GST_FORMAT_BYTES:
      switch (*dst_format) {
        case GST_FORMAT_TIME:
          *dst_value =
              gst_util_uint64_scale_int (src_value, GST_SECOND,
              sample_size * samplerate);
          break;
        case GST_FORMAT_DEFAULT:
          *dst_value = gst_util_uint64_scale_int (src_value, 1, sample_size);
          break;
        default:
          res = FALSE;
          break;
      }
      break;
    case GST_FORMAT_TIME:
      switch (*dst_format) {
        case GST_FORMAT_BYTES:
          *dst_value =
              gst_util_uint64_scale_int (src_value, samplerate * sample_size,
              GST_SECOND);
          break;
        case GST_FORMAT_DEFAULT:
          *dst_value =
              gst_util_uint64_scale_int (src_value, samplerate, GST_SECOND);
          break;
        default:
          res = FALSE;
          break;
      }
      break;
    case GST_FORMAT_DEFAULT:
      switch (*dst_format) {
        case GST_FORMAT_BYTES:
          *dst_value = gst_util_uint64_scale_int (src_value, sample_size, 1);
          break;
        case GST_FORMAT_TIME:
          *dst_value =
              gst_util_uint64_scale_int (src_value, GST_SECOND, samplerate);
          break;
        default:
          res = FALSE;
          break;
      }
      break;
    default:
      res = FALSE;
      break;
  }

  return res;
}

static gboolean
gst_pitch_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstPitch *pitch;
  gboolean res = FALSE;
  gfloat stream_time_ratio;
  gint64 next_buffer_offset;
  GstClockTime next_buffer_time;

  pitch = GST_PITCH (parent);

  GST_LOG ("%s query", GST_QUERY_TYPE_NAME (query));

  GST_OBJECT_LOCK (pitch);
  stream_time_ratio = pitch->priv->stream_time_ratio;
  next_buffer_time = pitch->next_buffer_time;
  next_buffer_offset = pitch->next_buffer_offset;
  GST_OBJECT_UNLOCK (pitch);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:{
      GstFormat format;
      gint64 duration;

      if (!gst_pad_query_default (pad, parent, query)) {
        GST_DEBUG_OBJECT (pitch, "upstream provided no duration");
        break;
      }

      gst_query_parse_duration (query, &format, &duration);

      if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT) {
        GST_DEBUG_OBJECT (pitch, "not TIME or DEFAULT format");
        break;
      }
      GST_LOG_OBJECT (pitch, "upstream duration: %" G_GINT64_FORMAT, duration);
      duration = (gint64) (duration / stream_time_ratio);
      GST_LOG_OBJECT (pitch, "our duration: %" G_GINT64_FORMAT, duration);
      gst_query_set_duration (query, format, duration);
      res = TRUE;
      break;
    }
    case GST_QUERY_POSITION:{
      GstFormat dst_format;
      gint64 dst_value;

      gst_query_parse_position (query, &dst_format, &dst_value);

      if (dst_format != GST_FORMAT_TIME && dst_format != GST_FORMAT_DEFAULT) {
        GST_DEBUG_OBJECT (pitch, "not TIME or DEFAULT format");
        break;
      }

      if (dst_format == GST_FORMAT_TIME) {
        dst_value = next_buffer_time;
        res = TRUE;
      } else {
        dst_value = next_buffer_offset;
        res = TRUE;
      }

      if (res) {
        GST_LOG_OBJECT (pitch, "our position: %" G_GINT64_FORMAT, dst_value);
        gst_query_set_position (query, dst_format, dst_value);
      }
      break;
    }
    case GST_QUERY_CONVERT:{
      GstFormat src_format, dst_format;
      gint64 src_value, dst_value;

      gst_query_parse_convert (query, &src_format, &src_value,
          &dst_format, NULL);

      res = gst_pitch_convert (pitch, src_format, src_value,
          &dst_format, &dst_value);

      if (res) {
        gst_query_set_convert (query, src_format, src_value,
            dst_format, dst_value);
      }
      break;
    }
    case GST_QUERY_LATENCY:
    {
      GstClockTime min, max;
      gboolean live;
      GstPad *peer;

      if ((peer = gst_pad_get_peer (pitch->sinkpad))) {
        if ((res = gst_pad_query (peer, query))) {
          gst_query_parse_latency (query, &live, &min, &max);

          GST_DEBUG ("Peer latency: min %"
              GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
              GST_TIME_ARGS (min), GST_TIME_ARGS (max));

          /* add our own latency */

          GST_DEBUG ("Our latency: min %" GST_TIME_FORMAT
              ", max %" GST_TIME_FORMAT,
              GST_TIME_ARGS (pitch->min_latency),
              GST_TIME_ARGS (pitch->max_latency));

          min += pitch->min_latency;
          if (max != GST_CLOCK_TIME_NONE)
            max += pitch->max_latency;

          GST_DEBUG ("Calculated total latency : min %"
              GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
              GST_TIME_ARGS (min), GST_TIME_ARGS (max));
          gst_query_set_latency (query, live, min, max);
        }
        gst_object_unref (peer);
      }
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

  return res;
}

/* this function returns FALSE if not enough data is known to transform the
 * segment into proper downstream values.  If the function does return false
 * the segment should be stalled until enough information is available.
 * If the funtion returns TRUE, event will be replaced by the new downstream
 * compatible event.
 */
static gboolean
gst_pitch_process_segment (GstPitch * pitch, GstEvent ** event)
{
  gint seqnum;
  gdouble out_seg_rate, our_arate;
  gfloat stream_time_ratio;
  GstSegment seg;

  g_return_val_if_fail (event, FALSE);

  GST_OBJECT_LOCK (pitch);
  stream_time_ratio = pitch->priv->stream_time_ratio;
  out_seg_rate = pitch->out_seg_rate;
  GST_OBJECT_UNLOCK (pitch);

  gst_event_copy_segment (*event, &seg);

  if (seg.format != GST_FORMAT_TIME && seg.format != GST_FORMAT_DEFAULT) {
    GST_WARNING_OBJECT (pitch,
        "Only NEWSEGMENT in TIME or DEFAULT format supported, sending"
        "open ended NEWSEGMENT in TIME format.");
    seg.format = GST_FORMAT_TIME;
    seg.start = 0;
    seg.stop = -1;
    seg.time = 0;
  }

  /* Figure out how much of the incoming 'rate' we'll apply ourselves */
  our_arate = seg.rate / out_seg_rate;
  /* update the output rate variables */
  seg.rate = out_seg_rate;
  seg.applied_rate *= our_arate;

  GST_LOG_OBJECT (pitch->sinkpad, "in segment %" GST_SEGMENT_FORMAT, &seg);

  stream_time_ratio = pitch->tempo * pitch->rate * pitch->seg_arate;

  if (stream_time_ratio == 0) {
    GST_LOG_OBJECT (pitch->sinkpad, "stream_time_ratio is zero");
    return FALSE;
  }

  /* Update the playback rate */
  GST_OBJECT_LOCK (pitch);
  pitch->seg_arate = our_arate;
  pitch->priv->stream_time_ratio = stream_time_ratio;
  pitch->priv->st->setTempo (pitch->tempo * pitch->seg_arate);
  GST_OBJECT_UNLOCK (pitch);

  seg.start = (gint64) (seg.start / stream_time_ratio);
  seg.position = (gint64) (seg.position / stream_time_ratio);
  if (seg.stop != (guint64) - 1)
    seg.stop = (gint64) (seg.stop / stream_time_ratio);
  seg.time = (gint64) (seg.time / stream_time_ratio);

  GST_LOG_OBJECT (pitch->sinkpad, "out segment %" GST_SEGMENT_FORMAT, &seg);

  seqnum = gst_event_get_seqnum (*event);
  gst_event_unref (*event);
  *event = gst_event_new_segment (&seg);
  gst_event_set_seqnum (*event, seqnum);

  return TRUE;
}

static gboolean
gst_pitch_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  GstPitch *pitch;

  pitch = GST_PITCH (parent);

  GST_LOG_OBJECT (pad, "received %s event", GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_pitch_flush_buffer (pitch, FALSE);
      pitch->priv->st->clear ();
      pitch->next_buffer_offset = 0;
      pitch->next_buffer_time = GST_CLOCK_TIME_NONE;
      pitch->min_latency = pitch->max_latency = 0;
      break;
    case GST_EVENT_EOS:
      gst_pitch_flush_buffer (pitch, TRUE);
      pitch->priv->st->clear ();
      pitch->min_latency = pitch->max_latency = 0;
      break;
    case GST_EVENT_SEGMENT:
      if (!gst_pitch_process_segment (pitch, &event)) {
        GST_LOG_OBJECT (pad, "not enough data known, stalling segment");
        if (GST_PITCH_GET_PRIVATE (pitch)->pending_segment)
          gst_event_unref (GST_PITCH_GET_PRIVATE (pitch)->pending_segment);
        GST_PITCH_GET_PRIVATE (pitch)->pending_segment = event;
        event = NULL;
      }
      pitch->priv->st->clear ();
      pitch->min_latency = pitch->max_latency = 0;
      break;
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_pitch_setcaps (pitch, caps);
      if (!res) {
        gst_event_unref (event);
        goto done;
      }
    }
    default:
      break;
  }

  /* and forward it */
  if (event)
    res = gst_pad_event_default (pad, parent, event);

done:
  return res;
}

static void
gst_pitch_update_latency (GstPitch * pitch, GstClockTime timestamp)
{
  GstClockTimeDiff current_latency, min_latency, max_latency;

  current_latency =
      (GstClockTimeDiff) (timestamp / pitch->priv->stream_time_ratio) -
      pitch->next_buffer_time;

  min_latency = MIN (pitch->min_latency, current_latency);
  max_latency = MAX (pitch->max_latency, current_latency);

  if (pitch->min_latency != min_latency || pitch->max_latency != max_latency) {
    pitch->min_latency = min_latency;
    pitch->max_latency = max_latency;

    /* FIXME: what about the LATENCY event? It only has
     * one latency value, should it be current, min or max?
     * Should it include upstream latencies?
     */

    gst_element_post_message (GST_ELEMENT (pitch),
        gst_message_new_latency (GST_OBJECT (pitch)));
  }
}

static GstFlowReturn
gst_pitch_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstPitch *pitch;
  GstPitchPrivate *priv;
  GstClockTime timestamp;
  GstMapInfo info;

  pitch = GST_PITCH (parent);
  priv = GST_PITCH_GET_PRIVATE (pitch);

  timestamp = GST_BUFFER_TIMESTAMP (buffer);

  // Remember the first time and corresponding offset
  if (!GST_CLOCK_TIME_IS_VALID (pitch->next_buffer_time)) {
    gfloat stream_time_ratio;
    GstFormat out_format = GST_FORMAT_DEFAULT;

    GST_OBJECT_LOCK (pitch);
    stream_time_ratio = priv->stream_time_ratio;
    GST_OBJECT_UNLOCK (pitch);

    pitch->next_buffer_time = timestamp / stream_time_ratio;
    gst_pitch_convert (pitch, GST_FORMAT_TIME, timestamp, &out_format,
        &pitch->next_buffer_offset);
  }

  gst_object_sync_values (GST_OBJECT (pitch), pitch->next_buffer_time);

  /* push the received samples on the soundtouch buffer */
  GST_LOG_OBJECT (pitch, "incoming buffer (%d samples) %" GST_TIME_FORMAT,
      (gint) (gst_buffer_get_size (buffer) / pitch->info.bpf),
      GST_TIME_ARGS (timestamp));

  if (GST_PITCH_GET_PRIVATE (pitch)->pending_segment) {
    GstEvent *event =
        gst_event_copy (GST_PITCH_GET_PRIVATE (pitch)->pending_segment);

    GST_LOG_OBJECT (pitch, "processing stalled segment");
    if (!gst_pitch_process_segment (pitch, &event)) {
      gst_buffer_unref (buffer);
      gst_event_unref (event);
      return GST_FLOW_ERROR;
    }

    if (!gst_pad_event_default (pitch->sinkpad, parent, event)) {
      gst_buffer_unref (buffer);
      gst_event_unref (event);
      return GST_FLOW_ERROR;
    }

    gst_event_unref (GST_PITCH_GET_PRIVATE (pitch)->pending_segment);
    GST_PITCH_GET_PRIVATE (pitch)->pending_segment = NULL;
  }

  gst_buffer_map (buffer, &info, GST_MAP_READ);
  priv->st->putSamples ((soundtouch::SAMPLETYPE *) info.data, info.size / pitch->info.bpf);
  gst_buffer_unmap (buffer, &info);
  gst_buffer_unref (buffer);

  /* Calculate latency */

  gst_pitch_update_latency (pitch, timestamp);
  /* and try to extract some samples from the soundtouch buffer */
  if (!priv->st->isEmpty ()) {
    GstBuffer *out_buffer;

    out_buffer = gst_pitch_prepare_buffer (pitch);
    if (out_buffer)
      return gst_pitch_forward_buffer (pitch, out_buffer);
  }

  return GST_FLOW_OK;
}

static GstStateChangeReturn
gst_pitch_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstPitch *pitch = GST_PITCH (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      pitch->next_buffer_time = GST_CLOCK_TIME_NONE;
      pitch->next_buffer_offset = 0;
      pitch->priv->st->clear ();
      pitch->min_latency = pitch->max_latency = 0;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret != GST_STATE_CHANGE_SUCCESS)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      if (GST_PITCH_GET_PRIVATE (pitch)->pending_segment) {
        gst_event_unref (GST_PITCH_GET_PRIVATE (pitch)->pending_segment);
        GST_PITCH_GET_PRIVATE (pitch)->pending_segment = NULL;
      }
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
    default:
      break;
  }

  return ret;
}
