/* 
 * GStreamer
 * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * 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-audioecho
 *
 * audioecho adds an echo or (simple) reverb effect to an audio stream. The echo
 * delay, intensity and the percentage of feedback can be configured.
 *
 * For getting an echo effect you have to set the delay to a larger value,
 * for example 200ms and more. Everything below will result in a simple
 * reverb effect, which results in a slightly metallic sound.
 *
 * Use the max-delay property to set the maximum amount of delay that
 * will be used. This can only be set before going to the PAUSED or PLAYING
 * state and will be set to the current delay by default.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 autoaudiosrc ! audioconvert ! audioecho delay=500000000 intensity=0.6 feedback=0.4 ! audioconvert ! autoaudiosink
 * gst-launch-1.0 filesrc location="melo1.ogg" ! decodebin ! audioconvert ! audioecho delay=50000000 intensity=0.6 feedback=0.4 ! audioconvert ! autoaudiosink
 * ]|
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/audio/audio.h>
#include <gst/audio/gstaudiofilter.h>

#include "audioecho.h"

#define GST_CAT_DEFAULT gst_audio_echo_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0,
  PROP_DELAY,
  PROP_MAX_DELAY,
  PROP_INTENSITY,
  PROP_FEEDBACK
};

#define ALLOWED_CAPS \
    "audio/x-raw,"                                                 \
    " format=(string) {"GST_AUDIO_NE(F32)","GST_AUDIO_NE(F64)"}, " \
    " rate=(int)[1,MAX],"                                          \
    " channels=(int)[1,MAX],"                                      \
    " layout=(string) interleaved"

#define gst_audio_echo_parent_class parent_class
G_DEFINE_TYPE (GstAudioEcho, gst_audio_echo, GST_TYPE_AUDIO_FILTER);

static void gst_audio_echo_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_audio_echo_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_audio_echo_finalize (GObject * object);

static gboolean gst_audio_echo_setup (GstAudioFilter * self,
    const GstAudioInfo * info);
static gboolean gst_audio_echo_stop (GstBaseTransform * base);
static GstFlowReturn gst_audio_echo_transform_ip (GstBaseTransform * base,
    GstBuffer * buf);

static void gst_audio_echo_transform_float (GstAudioEcho * self,
    gfloat * data, guint num_samples);
static void gst_audio_echo_transform_double (GstAudioEcho * self,
    gdouble * data, guint num_samples);

/* GObject vmethod implementations */

static void
gst_audio_echo_class_init (GstAudioEchoClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;
  GstBaseTransformClass *basetransform_class = (GstBaseTransformClass *) klass;
  GstAudioFilterClass *audioself_class = (GstAudioFilterClass *) klass;
  GstCaps *caps;

  GST_DEBUG_CATEGORY_INIT (gst_audio_echo_debug, "audioecho", 0,
      "audioecho element");

  gobject_class->set_property = gst_audio_echo_set_property;
  gobject_class->get_property = gst_audio_echo_get_property;
  gobject_class->finalize = gst_audio_echo_finalize;

  g_object_class_install_property (gobject_class, PROP_DELAY,
      g_param_spec_uint64 ("delay", "Delay",
          "Delay of the echo in nanoseconds", 1, G_MAXUINT64,
          1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
          | GST_PARAM_CONTROLLABLE));

  g_object_class_install_property (gobject_class, PROP_MAX_DELAY,
      g_param_spec_uint64 ("max-delay", "Maximum Delay",
          "Maximum delay of the echo in nanoseconds"
          " (can't be changed in PLAYING or PAUSED state)",
          1, G_MAXUINT64, 1,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
          GST_PARAM_MUTABLE_READY));

  g_object_class_install_property (gobject_class, PROP_INTENSITY,
      g_param_spec_float ("intensity", "Intensity",
          "Intensity of the echo", 0.0, 1.0,
          0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
          | GST_PARAM_CONTROLLABLE));

  g_object_class_install_property (gobject_class, PROP_FEEDBACK,
      g_param_spec_float ("feedback", "Feedback",
          "Amount of feedback", 0.0, 1.0,
          0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
          | GST_PARAM_CONTROLLABLE));

  gst_element_class_set_static_metadata (gstelement_class, "Audio echo",
      "Filter/Effect/Audio",
      "Adds an echo or reverb effect to an audio stream",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  caps = gst_caps_from_string (ALLOWED_CAPS);
  gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
      caps);
  gst_caps_unref (caps);

  audioself_class->setup = GST_DEBUG_FUNCPTR (gst_audio_echo_setup);
  basetransform_class->transform_ip =
      GST_DEBUG_FUNCPTR (gst_audio_echo_transform_ip);
  basetransform_class->stop = GST_DEBUG_FUNCPTR (gst_audio_echo_stop);
}

static void
gst_audio_echo_init (GstAudioEcho * self)
{
  self->delay = 1;
  self->max_delay = 1;
  self->intensity = 0.0;
  self->feedback = 0.0;

  g_mutex_init (&self->lock);

  gst_base_transform_set_in_place (GST_BASE_TRANSFORM (self), TRUE);
}

static void
gst_audio_echo_finalize (GObject * object)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (object);

  g_free (self->buffer);
  self->buffer = NULL;

  g_mutex_clear (&self->lock);

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

static void
gst_audio_echo_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (object);

  switch (prop_id) {
    case PROP_DELAY:{
      guint64 max_delay, delay;
      guint rate;

      g_mutex_lock (&self->lock);
      delay = g_value_get_uint64 (value);
      max_delay = self->max_delay;

      if (delay > max_delay && GST_STATE (self) > GST_STATE_READY) {
        GST_WARNING_OBJECT (self, "New delay (%" GST_TIME_FORMAT ") "
            "is larger than maximum delay (%" GST_TIME_FORMAT ")",
            GST_TIME_ARGS (delay), GST_TIME_ARGS (max_delay));
        self->delay = max_delay;
      } else {
        self->delay = delay;
        self->max_delay = MAX (delay, max_delay);
      }
      rate = GST_AUDIO_FILTER_RATE (self);
      if (rate > 0)
        self->delay_frames =
            MAX (gst_util_uint64_scale (self->delay, rate, GST_SECOND), 1);

      g_mutex_unlock (&self->lock);
      break;
    }
    case PROP_MAX_DELAY:{
      guint64 max_delay, delay;

      g_mutex_lock (&self->lock);
      max_delay = g_value_get_uint64 (value);
      delay = self->delay;

      if (GST_STATE (self) > GST_STATE_READY) {
        GST_ERROR_OBJECT (self, "Can't change maximum delay in"
            " PLAYING or PAUSED state");
      } else {
        self->delay = delay;
        self->max_delay = max_delay;
      }
      g_mutex_unlock (&self->lock);
      break;
    }
    case PROP_INTENSITY:{
      g_mutex_lock (&self->lock);
      self->intensity = g_value_get_float (value);
      g_mutex_unlock (&self->lock);
      break;
    }
    case PROP_FEEDBACK:{
      g_mutex_lock (&self->lock);
      self->feedback = g_value_get_float (value);
      g_mutex_unlock (&self->lock);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_audio_echo_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (object);

  switch (prop_id) {
    case PROP_DELAY:
      g_mutex_lock (&self->lock);
      g_value_set_uint64 (value, self->delay);
      g_mutex_unlock (&self->lock);
      break;
    case PROP_MAX_DELAY:
      g_mutex_lock (&self->lock);
      g_value_set_uint64 (value, self->max_delay);
      g_mutex_unlock (&self->lock);
      break;
    case PROP_INTENSITY:
      g_mutex_lock (&self->lock);
      g_value_set_float (value, self->intensity);
      g_mutex_unlock (&self->lock);
      break;
    case PROP_FEEDBACK:
      g_mutex_lock (&self->lock);
      g_value_set_float (value, self->feedback);
      g_mutex_unlock (&self->lock);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* GstAudioFilter vmethod implementations */

static gboolean
gst_audio_echo_setup (GstAudioFilter * base, const GstAudioInfo * info)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (base);
  gboolean ret = TRUE;

  switch (GST_AUDIO_INFO_FORMAT (info)) {
    case GST_AUDIO_FORMAT_F32:
      self->process = (GstAudioEchoProcessFunc)
          gst_audio_echo_transform_float;
      break;
    case GST_AUDIO_FORMAT_F64:
      self->process = (GstAudioEchoProcessFunc)
          gst_audio_echo_transform_double;
      break;
    default:
      ret = FALSE;
      break;
  }

  g_free (self->buffer);
  self->buffer = NULL;
  self->buffer_pos = 0;
  self->buffer_size = 0;
  self->buffer_size_frames = 0;

  return ret;
}

static gboolean
gst_audio_echo_stop (GstBaseTransform * base)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (base);

  g_free (self->buffer);
  self->buffer = NULL;
  self->buffer_pos = 0;
  self->buffer_size = 0;
  self->buffer_size_frames = 0;

  return TRUE;
}

#define TRANSFORM_FUNC(name, type) \
static void \
gst_audio_echo_transform_##name (GstAudioEcho * self, \
    type * data, guint num_samples) \
{ \
  type *buffer = (type *) self->buffer; \
  guint channels = GST_AUDIO_FILTER_CHANNELS (self); \
  guint rate = GST_AUDIO_FILTER_RATE (self); \
  guint i, j; \
  guint echo_index = self->buffer_size_frames - self->delay_frames; \
  gdouble echo_off = ((((gdouble) self->delay) * rate) / GST_SECOND) - self->delay_frames; \
  \
  if (echo_off < 0.0) \
    echo_off = 0.0; \
  \
  num_samples /= channels; \
  \
  for (i = 0; i < num_samples; i++) { \
    guint echo0_index = ((echo_index + self->buffer_pos) % self->buffer_size_frames) * channels; \
    guint echo1_index = ((echo_index + self->buffer_pos +1) % self->buffer_size_frames) * channels; \
    guint rbout_index = (self->buffer_pos % self->buffer_size_frames) * channels; \
    for (j = 0; j < channels; j++) { \
      gdouble in = data[i*channels + j]; \
      gdouble echo0 = buffer[echo0_index + j]; \
      gdouble echo1 = buffer[echo1_index + j]; \
      gdouble echo = echo0 + (echo1-echo0)*echo_off; \
      type out = in + self->intensity * echo; \
      \
      data[i*channels + j] = out; \
      \
      buffer[rbout_index + j] = in + self->feedback * echo; \
    } \
    self->buffer_pos = (self->buffer_pos + 1) % self->buffer_size_frames; \
  } \
}

TRANSFORM_FUNC (float, gfloat);
TRANSFORM_FUNC (double, gdouble);

/* GstBaseTransform vmethod implementations */
static GstFlowReturn
gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf)
{
  GstAudioEcho *self = GST_AUDIO_ECHO (base);
  guint num_samples;
  GstClockTime timestamp, stream_time;
  GstMapInfo map;

  g_mutex_lock (&self->lock);
  timestamp = GST_BUFFER_TIMESTAMP (buf);
  stream_time =
      gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (self, "sync to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (stream_time))
    gst_object_sync_values (GST_OBJECT (self), stream_time);

  if (self->buffer == NULL) {
    guint bpf, rate;

    bpf = GST_AUDIO_FILTER_BPF (self);
    rate = GST_AUDIO_FILTER_RATE (self);

    self->delay_frames =
        MAX (gst_util_uint64_scale (self->delay, rate, GST_SECOND), 1);
    self->buffer_size_frames =
        MAX (gst_util_uint64_scale (self->max_delay, rate, GST_SECOND), 1);

    self->buffer_size = self->buffer_size_frames * bpf;
    self->buffer = g_try_malloc0 (self->buffer_size);
    self->buffer_pos = 0;

    if (self->buffer == NULL) {
      g_mutex_unlock (&self->lock);
      GST_ERROR_OBJECT (self, "Failed to allocate %u bytes", self->buffer_size);
      return GST_FLOW_ERROR;
    }
  }

  gst_buffer_map (buf, &map, GST_MAP_READWRITE);
  num_samples = map.size / GST_AUDIO_FILTER_BPS (self);

  self->process (self, map.data, num_samples);

  gst_buffer_unmap (buf, &map);
  g_mutex_unlock (&self->lock);

  return GST_FLOW_OK;
}
