/*
 * GStreamer
 * Copyright (C) 2011 Stefan Sauer <ensonic@users.sf.net>
 *
 * 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.
 */
/*
 * Freeverb
 *
 * Written by Jezar at Dreampoint, June 2000
 * http://www.dreampoint.co.uk
 * This code is public domain
 *
 * Translated to C by Peter Hanappe, Mai 2001
 * Transformed into a GStreamer plugin by Stefan Sauer, Nov 2011
 */

/**
 * SECTION:element-freeverb
 *
 * Reverberation/room effect.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch audiotestsrc wave=saw ! freeverb ! autoaudiosink
 * gst-launch filesrc location="melo1.ogg" ! decodebin ! audioconvert ! freeverb ! autoaudiosink
 * ]|
 * </refsect2>
 */

/* FIXME:
 * - add mono-to-mono, then we might also need stereo-to-mono ?
 */

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

#include <math.h>
#include <stdlib.h>

#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/controller/gstcontroller.h>

#include "gstfreeverb.h"

#define GST_CAT_DEFAULT gst_freeverb_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0,
  PROP_ROOM_SIZE,
  PROP_DAMPING,
  PROP_PAN_WIDTH,
  PROP_LEVEL
};

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw-float, "
        "rate = (int) [ 1, MAX ], "
        "channels = (int) [ 1, 2 ], "
        "endianness = (int) BYTE_ORDER, " "width = (int) 32; "
        "audio/x-raw-int, "
        "rate = (int) [ 1, MAX ], "
        "channels = (int) [ 1, 2 ], "
        "endianness = (int) BYTE_ORDER, "
        "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true")
    );

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw-float, "
        "rate = (int) [ 1, MAX ], "
        "channels = (int) 2, "
        "endianness = (int) BYTE_ORDER, " "width = (int) 32; "
        "audio/x-raw-int, "
        "rate = (int) [ 1, MAX ], "
        "channels = (int) 2, "
        "endianness = (int) BYTE_ORDER, "
        "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true")
    );

#define _do_init(type) {                                                       \
  const GInterfaceInfo preset_interface_info = { NULL, NULL, NULL };           \
  g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_interface_info); \
                                                                               \
  GST_DEBUG_CATEGORY_INIT (gst_freeverb_debug, "freeverb", 0,                  \
      "freeverb element");                                                     \
}

GST_BOILERPLATE_FULL (GstFreeverb, gst_freeverb, GstBaseTransform,
    GST_TYPE_BASE_TRANSFORM, _do_init);

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

static void gst_freeverb_finalize (GObject * object);

static gboolean gst_freeverb_get_unit_size (GstBaseTransform * base,
    GstCaps * caps, guint * size);
static GstCaps *gst_freeverb_transform_caps (GstBaseTransform * base,
    GstPadDirection direction, GstCaps * caps);
static gboolean gst_freeverb_set_caps (GstBaseTransform * base,
    GstCaps * incaps, GstCaps * outcaps);

static GstFlowReturn gst_freeverb_transform (GstBaseTransform * base,
    GstBuffer * inbuf, GstBuffer * outbuf);

static gboolean gst_freeverb_transform_m2s_int (GstFreeverb * filter,
    gint16 * idata, gint16 * odata, guint num_samples);
static gboolean gst_freeverb_transform_s2s_int (GstFreeverb * filter,
    gint16 * idata, gint16 * odata, guint num_samples);
static gboolean gst_freeverb_transform_m2s_float (GstFreeverb * filter,
    gfloat * idata, gfloat * odata, guint num_samples);
static gboolean gst_freeverb_transform_s2s_float (GstFreeverb * filter,
    gfloat * idata, gfloat * odata, guint num_samples);


/* Table with processing functions: [channels][format] */
static GstFreeverbProcessFunc process_functions[2][2] = {
  {
        (GstFreeverbProcessFunc) gst_freeverb_transform_m2s_int,
        (GstFreeverbProcessFunc) gst_freeverb_transform_m2s_float,
      },
  {
        (GstFreeverbProcessFunc) gst_freeverb_transform_s2s_int,
        (GstFreeverbProcessFunc) gst_freeverb_transform_s2s_float,
      }
};

/***************************************************************
 *
 *                           REVERB
 */

/* Denormalising:
 *
 * Another method fixes the problem cheaper: Use a small DC-offset in
 * the filter calculations.  Now the signals converge not against 0,
 * but against the offset.  The constant offset is invisible from the
 * outside world (i.e. it does not appear at the output.  There is a
 * very small turn-on transient response, which should not cause
 * problems.
 */

//#define DC_OFFSET 0
#define DC_OFFSET 1e-8
//#define DC_OFFSET 0.001f

/* all pass filter */

typedef struct _freeverb_allpass
{
  gfloat feedback;
  gfloat *buffer;
  gint bufsize;
  gint bufidx;
} freeverb_allpass;

static void
freeverb_allpass_setbuffer (freeverb_allpass * allpass, gint size)
{
  allpass->bufidx = 0;
  allpass->buffer = g_new (gfloat, size);
  allpass->bufsize = size;
}

static void
freeverb_allpass_release (freeverb_allpass * allpass)
{
  g_free (allpass->buffer);
}

static void
freeverb_allpass_init (freeverb_allpass * allpass)
{
  gint i, len = allpass->bufsize;
  gfloat *buf = allpass->buffer;

  for (i = 0; i < len; i++) {
    buf[i] = DC_OFFSET;         /* this is not 100 % correct. */
  }
}

static void
freeverb_allpass_setfeedback (freeverb_allpass * allpass, gfloat val)
{
  allpass->feedback = val;
}

/*
static gfloat
freeverb_allpass_getfeedback(freeverb_allpass* allpass)
{
  return allpass->feedback;
}*/

#define freeverb_allpass_process(_allpass, _input_1) \
{ \
  gfloat output; \
  gfloat bufout; \
  bufout = _allpass.buffer[_allpass.bufidx]; \
  output = bufout-_input_1; \
  _allpass.buffer[_allpass.bufidx] = _input_1 + (bufout * _allpass.feedback); \
  if (++_allpass.bufidx >= _allpass.bufsize) { \
    _allpass.bufidx = 0; \
  } \
  _input_1 = output; \
}

/* comb filter */

typedef struct _freeverb_comb
{
  gfloat feedback;
  gfloat filterstore;
  gfloat damp1;
  gfloat damp2;
  gfloat *buffer;
  gint bufsize;
  gint bufidx;
} freeverb_comb;

static void
freeverb_comb_setbuffer (freeverb_comb * comb, gint size)
{
  comb->filterstore = 0;
  comb->bufidx = 0;
  comb->buffer = g_new (gfloat, size);
  comb->bufsize = size;
}

static void
freeverb_comb_release (freeverb_comb * comb)
{
  g_free (comb->buffer);
}

static void
freeverb_comb_init (freeverb_comb * comb)
{
  gint i, len = comb->bufsize;
  gfloat *buf = comb->buffer;

  for (i = 0; i < len; i++) {
    buf[i] = DC_OFFSET;         /* This is not 100 % correct. */
  }
}

static void
freeverb_comb_setdamp (freeverb_comb * comb, gfloat val)
{
  comb->damp1 = val;
  comb->damp2 = 1 - val;
}

/*
static gfloat
freeverb_comb_getdamp(freeverb_comb* comb)
{
  return comb->damp1;
}*/

static void
freeverb_comb_setfeedback (freeverb_comb * comb, gfloat val)
{
  comb->feedback = val;
}

/*
static gfloat
freeverb_comb_getfeedback(freeverb_comb* comb)
{
  return comb->feedback;
}*/

#define freeverb_comb_process(_comb, _input_1, _output) \
{ \
  gfloat _tmp = _comb.buffer[_comb.bufidx]; \
  _comb.filterstore = (_tmp * _comb.damp2) + (_comb.filterstore * _comb.damp1); \
  _comb.buffer[_comb.bufidx] = _input_1 + (_comb.filterstore * _comb.feedback); \
  if (++_comb.bufidx >= _comb.bufsize) { \
    _comb.bufidx = 0; \
  } \
  _output += _tmp; \
}

#define numcombs 8
#define numallpasses 4
#define	fixedgain 0.015f
#define scalewet 1.0f
#define scaledry 1.0f
#define scaledamp 1.0f
#define scaleroom 0.28f
#define offsetroom 0.7f
#define stereospread 23

/* These values assume 44.1KHz sample rate
 * they will need scaling for 96KHz (or other) sample rates.
 * The values were obtained by listening tests.
 */
#define combtuningL1 1116
#define combtuningR1 (1116 + stereospread)
#define combtuningL2 1188
#define combtuningR2 (1188 + stereospread)
#define combtuningL3 1277
#define combtuningR3 (1277 + stereospread)
#define combtuningL4 1356
#define combtuningR4 (1356 + stereospread)
#define combtuningL5 1422
#define combtuningR5 (1422 + stereospread)
#define combtuningL6 1491
#define combtuningR6 (1491 + stereospread)
#define combtuningL7 1557
#define combtuningR7 (1557 + stereospread)
#define combtuningL8 1617
#define combtuningR8 (1617 + stereospread)
#define allpasstuningL1 556
#define allpasstuningR1 (556 + stereospread)
#define allpasstuningL2 441
#define allpasstuningR2 (441 + stereospread)
#define allpasstuningL3 341
#define allpasstuningR3 (341 + stereospread)
#define allpasstuningL4 225
#define allpasstuningR4 (225 + stereospread)

struct _GstFreeverbPrivate
{
  gfloat roomsize;
  gfloat damp;
  gfloat wet, wet1, wet2, dry;
  gfloat width;
  gfloat gain;
  /*
     The following are all declared inline
     to remove the need for dynamic allocation
     with its subsequent error-checking messiness
   */
  /* Comb filters */
  freeverb_comb combL[numcombs];
  freeverb_comb combR[numcombs];
  /* Allpass filters */
  freeverb_allpass allpassL[numallpasses];
  freeverb_allpass allpassR[numallpasses];
};

static void
freeverb_revmodel_init (GstFreeverb * filter)
{
  GstFreeverbPrivate *priv = filter->priv;
  gint i;

  for (i = 0; i < numcombs; i++) {
    freeverb_comb_init (&priv->combL[i]);
    freeverb_comb_init (&priv->combR[i]);
  }
  for (i = 0; i < numallpasses; i++) {
    freeverb_allpass_init (&priv->allpassL[i]);
    freeverb_allpass_init (&priv->allpassR[i]);
  }
}

static void
freeverb_revmodel_free (GstFreeverb * filter)
{
  GstFreeverbPrivate *priv = filter->priv;
  gint i;

  for (i = 0; i < numcombs; i++) {
    freeverb_comb_release (&priv->combL[i]);
    freeverb_comb_release (&priv->combR[i]);
  }
  for (i = 0; i < numallpasses; i++) {
    freeverb_allpass_release (&priv->allpassL[i]);
    freeverb_allpass_release (&priv->allpassR[i]);
  }
}

/* GObject vmethod implementations */

static void
gst_freeverb_base_init (gpointer klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sink_template));
  gst_element_class_set_metadata (element_class, "Stereo positioning",
      "Filter/Effect/Audio",
      "Reverberation/room effect", "Stefan Sauer <ensonic@users.sf.net>");
}

static void
gst_freeverb_class_init (GstFreeverbClass * klass)
{
  GObjectClass *gobject_class;

  g_type_class_add_private (klass, sizeof (GstFreeverbPrivate));

  gobject_class = (GObjectClass *) klass;
  gobject_class->set_property = gst_freeverb_set_property;
  gobject_class->get_property = gst_freeverb_get_property;
  gobject_class->finalize = gst_freeverb_finalize;

  g_object_class_install_property (gobject_class, PROP_ROOM_SIZE,
      g_param_spec_float ("room-size", "Room size",
          "Size of the simulated room", 0.0, 1.0, 0.5,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
          G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_DAMPING,
      g_param_spec_float ("damping", "Damping", "Damping of high frequencies",
          0.0, 1.0, 0.2,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
          G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_PAN_WIDTH,
      g_param_spec_float ("width", "Width", "Stereo panorama width", 0.0, 1.0,
          1.0,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
          G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_LEVEL,
      g_param_spec_float ("level", "Level", "dry/wet level", 0.0, 1.0, 0.5,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
          G_PARAM_STATIC_STRINGS));

  GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size =
      GST_DEBUG_FUNCPTR (gst_freeverb_get_unit_size);
  GST_BASE_TRANSFORM_CLASS (klass)->transform_caps =
      GST_DEBUG_FUNCPTR (gst_freeverb_transform_caps);
  GST_BASE_TRANSFORM_CLASS (klass)->set_caps =
      GST_DEBUG_FUNCPTR (gst_freeverb_set_caps);
  GST_BASE_TRANSFORM_CLASS (klass)->transform =
      GST_DEBUG_FUNCPTR (gst_freeverb_transform);
}

static void
gst_freeverb_init (GstFreeverb * filter, GstFreeverbClass * klass)
{
  filter->priv =
      G_TYPE_INSTANCE_GET_PRIVATE (filter, GST_TYPE_FREEVERB,
      GstFreeverbPrivate);

  filter->width = 0;
  filter->channels = 0;
  filter->format_float = FALSE;
  filter->process = NULL;

  gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);

  freeverb_revmodel_init (filter);
}

static void
gst_freeverb_finalize (GObject * object)
{
  GstFreeverb *filter = GST_FREEVERB (object);

  freeverb_revmodel_free (filter);

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

static gboolean
gst_freeverb_set_process_function (GstFreeverb * filter)
{
  gint channel_index, format_index;

  /* set processing function */
  channel_index = filter->channels - 1;
  if (channel_index > 1 || channel_index < 0) {
    filter->process = NULL;
    return FALSE;
  }

  format_index = (filter->format_float) ? 1 : 0;

  filter->process = process_functions[channel_index][format_index];

  g_assert (filter->process);
  return TRUE;
}

static void
gst_freeverb_init_rev_model (GstFreeverb * filter)
{
  gfloat srfactor = filter->rate / 44100.0f;
  GstFreeverbPrivate *priv = filter->priv;

  freeverb_revmodel_free (filter);

  priv->gain = fixedgain;

  freeverb_comb_setbuffer (&priv->combL[0], combtuningL1 * srfactor);
  freeverb_comb_setbuffer (&priv->combR[0], combtuningR1 * srfactor);
  freeverb_comb_setbuffer (&priv->combL[1], combtuningL2 * srfactor);
  freeverb_comb_setbuffer (&priv->combR[1], combtuningR2 * srfactor);
  freeverb_comb_setbuffer (&priv->combL[2], combtuningL3 * srfactor);
  freeverb_comb_setbuffer (&priv->combR[2], combtuningR3 * srfactor);
  freeverb_comb_setbuffer (&priv->combL[3], combtuningL4 * srfactor);
  freeverb_comb_setbuffer (&priv->combR[3], combtuningR4 * srfactor);
  freeverb_comb_setbuffer (&priv->combL[4], combtuningL5 * srfactor);
  freeverb_comb_setbuffer (&priv->combR[4], combtuningR5 * srfactor);
  freeverb_comb_setbuffer (&priv->combL[5], combtuningL6 * srfactor);
  freeverb_comb_setbuffer (&priv->combR[5], combtuningR6 * srfactor);
  freeverb_comb_setbuffer (&priv->combL[6], combtuningL7 * srfactor);
  freeverb_comb_setbuffer (&priv->combR[6], combtuningR7 * srfactor);
  freeverb_comb_setbuffer (&priv->combL[7], combtuningL8 * srfactor);
  freeverb_comb_setbuffer (&priv->combR[7], combtuningR8 * srfactor);
  freeverb_allpass_setbuffer (&priv->allpassL[0], allpasstuningL1 * srfactor);
  freeverb_allpass_setbuffer (&priv->allpassR[0], allpasstuningR1 * srfactor);
  freeverb_allpass_setbuffer (&priv->allpassL[1], allpasstuningL2 * srfactor);
  freeverb_allpass_setbuffer (&priv->allpassR[1], allpasstuningR2 * srfactor);
  freeverb_allpass_setbuffer (&priv->allpassL[2], allpasstuningL3 * srfactor);
  freeverb_allpass_setbuffer (&priv->allpassR[2], allpasstuningR3 * srfactor);
  freeverb_allpass_setbuffer (&priv->allpassL[3], allpasstuningL4 * srfactor);
  freeverb_allpass_setbuffer (&priv->allpassR[3], allpasstuningR4 * srfactor);

  /* clear buffers */
  freeverb_revmodel_init (filter);

  /* set default values */
  freeverb_allpass_setfeedback (&priv->allpassL[0], 0.5f);
  freeverb_allpass_setfeedback (&priv->allpassR[0], 0.5f);
  freeverb_allpass_setfeedback (&priv->allpassL[1], 0.5f);
  freeverb_allpass_setfeedback (&priv->allpassR[1], 0.5f);
  freeverb_allpass_setfeedback (&priv->allpassL[2], 0.5f);
  freeverb_allpass_setfeedback (&priv->allpassR[2], 0.5f);
  freeverb_allpass_setfeedback (&priv->allpassL[3], 0.5f);
  freeverb_allpass_setfeedback (&priv->allpassR[3], 0.5f);
}

static void
gst_freeverb_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstFreeverb *filter = GST_FREEVERB (object);
  GstFreeverbPrivate *priv = filter->priv;
  gint i;

  switch (prop_id) {
    case PROP_ROOM_SIZE:
      filter->room_size = g_value_get_float (value);
      priv->roomsize = (filter->room_size * scaleroom) + offsetroom;
      for (i = 0; i < numcombs; i++) {
        freeverb_comb_setfeedback (&priv->combL[i], priv->roomsize);
        freeverb_comb_setfeedback (&priv->combR[i], priv->roomsize);
      }
      break;
    case PROP_DAMPING:
      filter->damping = g_value_get_float (value);
      priv->damp = filter->damping * scaledamp;
      for (i = 0; i < numcombs; i++) {
        freeverb_comb_setdamp (&priv->combL[i], priv->damp);
        freeverb_comb_setdamp (&priv->combR[i], priv->damp);
      }
      break;
    case PROP_PAN_WIDTH:
      filter->pan_width = g_value_get_float (value);
      priv->width = filter->pan_width;
      priv->wet1 = priv->wet * (priv->width / 2.0f + 0.5f);
      priv->wet2 = priv->wet * ((1.0f - priv->width) / 2.0f);
      break;
    case PROP_LEVEL:
      filter->level = g_value_get_float (value);
      priv->wet = filter->level * scalewet;
      priv->dry = (1.0 - filter->level) * scaledry;
      priv->wet1 = priv->wet * (priv->width / 2.0f + 0.5f);
      priv->wet2 = priv->wet * ((1.0f - priv->width) / 2.0f);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_freeverb_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstFreeverb *filter = GST_FREEVERB (object);

  switch (prop_id) {
    case PROP_ROOM_SIZE:
      g_value_set_float (value, filter->room_size);
      break;
    case PROP_DAMPING:
      g_value_set_float (value, filter->damping);
      break;
    case PROP_PAN_WIDTH:
      g_value_set_float (value, filter->pan_width);
      break;
    case PROP_LEVEL:
      g_value_set_float (value, filter->level);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* GstBaseTransform vmethod implementations */

static gboolean
gst_freeverb_get_unit_size (GstBaseTransform * base, GstCaps * caps,
    guint * size)
{
  gint width, channels;
  GstStructure *structure;
  gboolean ret;

  g_assert (size);

  /* this works for both float and int */
  structure = gst_caps_get_structure (caps, 0);
  ret = gst_structure_get_int (structure, "width", &width);
  ret &= gst_structure_get_int (structure, "channels", &channels);

  *size = width * channels / 8;

  GST_INFO_OBJECT (base, "unit size: %u", *size);

  return ret;
}

static GstCaps *
gst_freeverb_transform_caps (GstBaseTransform * base,
    GstPadDirection direction, GstCaps * caps)
{
  GstCaps *res;
  GstStructure *structure;

  /* transform caps gives one single caps so we can just replace
   * the channel property with our range. */
  res = gst_caps_copy (caps);
  structure = gst_caps_get_structure (res, 0);
  if (direction == GST_PAD_SRC) {
    GST_INFO_OBJECT (base, "allow 1-2 channels");
    gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
  } else {
    GST_INFO_OBJECT (base, "allow 2 channels");
    gst_structure_set (structure, "channels", G_TYPE_INT, 2, NULL);
  }

  return res;
}

static gboolean
gst_freeverb_set_caps (GstBaseTransform * base, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstFreeverb *filter = GST_FREEVERB (base);
  const GstStructure *structure;
  gboolean ret;
  gint width, rate;
  const gchar *fmt;

  /*GST_INFO ("incaps are %" GST_PTR_FORMAT, incaps); */

  structure = gst_caps_get_structure (incaps, 0);
  ret = gst_structure_get_int (structure, "channels", &filter->channels);
  if (!ret)
    goto no_channels;

  ret = gst_structure_get_int (structure, "width", &width);
  if (!ret)
    goto no_width;
  filter->width = width / 8;

  ret = gst_structure_get_int (structure, "rate", &rate);
  if (!ret)
    goto no_rate;
  filter->rate = rate;

  fmt = gst_structure_get_name (structure);
  if (!strcmp (fmt, "audio/x-raw-int"))
    filter->format_float = FALSE;
  else
    filter->format_float = TRUE;

  GST_DEBUG_OBJECT (filter, "try to process %s input_1 with %d channels", fmt,
      filter->channels);

  ret = gst_freeverb_set_process_function (filter);
  if (!ret)
    GST_WARNING_OBJECT (filter, "can't process input_1 with %d channels",
        filter->channels);

  gst_freeverb_init_rev_model (filter);
  filter->drained = FALSE;
  GST_INFO_OBJECT (base, "model configured");

  return ret;

no_channels:
  GST_DEBUG_OBJECT (filter, "no channels in caps");
  return ret;
no_width:
  GST_DEBUG_OBJECT (filter, "no width in caps");
  return ret;
no_rate:
  GST_DEBUG_OBJECT (filter, "no rate in caps");
  return ret;
}

static gboolean
gst_freeverb_transform_m2s_int (GstFreeverb * filter,
    gint16 * idata, gint16 * odata, guint num_samples)
{
  GstFreeverbPrivate *priv = filter->priv;
  gint i, k;
  gfloat out_l1, out_r1, input_1;
  gfloat out_l2, out_r2, input_2;
  gboolean drained = TRUE;

  for (k = 0; k < num_samples; k++) {

    out_l1 = out_r1 = 0.0;

    /* The original Freeverb code expects a stereo signal and 'input_1'
     * is set to the sum of the left and right input_1 sample. Since
     * this code works on a mono signal, 'input_1' is set to twice the
     * input_1 sample. */
    input_2 = (gfloat) * idata++;
    input_1 = (2.0f * input_2 + DC_OFFSET) * priv->gain;

    /* Accumulate comb filters in parallel */
    for (i = 0; i < numcombs; i++) {
      freeverb_comb_process (priv->combL[i], input_1, out_l1);
      freeverb_comb_process (priv->combR[i], input_1, out_r1);
    }
    /* Feed through allpasses in series */
    for (i = 0; i < numallpasses; i++) {
      freeverb_allpass_process (priv->allpassL[i], out_l1);
      freeverb_allpass_process (priv->allpassR[i], out_r1);
    }

    /* Remove the DC offset */
    out_l1 -= DC_OFFSET;
    out_r1 -= DC_OFFSET;

    /* Calculate output */
    out_l2 = out_l1 * priv->wet1 + out_r1 * priv->wet2 + input_2 * priv->dry;
    out_r2 = out_r1 * priv->wet1 + out_l1 * priv->wet2 + input_2 * priv->dry;
    *odata++ = (gint16) CLAMP (out_l2, G_MININT16, G_MAXINT16);
    *odata++ = (gint16) CLAMP (out_r2, G_MININT16, G_MAXINT16);

    if (abs (out_l2) > 0 || abs (out_r2) > 0)
      drained = FALSE;
  }
  return drained;
}

static gboolean
gst_freeverb_transform_s2s_int (GstFreeverb * filter,
    gint16 * idata, gint16 * odata, guint num_samples)
{
  GstFreeverbPrivate *priv = filter->priv;
  gint i, k;
  gfloat out_l1, out_r1, input_1l, input_1r;
  gfloat out_l2, out_r2, input_2l, input_2r;
  gboolean drained = TRUE;

  for (k = 0; k < num_samples; k++) {

    out_l1 = out_r1 = 0.0;

    input_2l = (gfloat) * idata++;
    input_2r = (gfloat) * idata++;
    input_1l = (input_2l + DC_OFFSET) * priv->gain;
    input_1r = (input_2r + DC_OFFSET) * priv->gain;

    /* Accumulate comb filters in parallel */
    for (i = 0; i < numcombs; i++) {
      freeverb_comb_process (priv->combL[i], input_1l, out_l1);
      freeverb_comb_process (priv->combR[i], input_1r, out_r1);
    }
    /* Feed through allpasses in series */
    for (i = 0; i < numallpasses; i++) {
      freeverb_allpass_process (priv->allpassL[i], out_l1);
      freeverb_allpass_process (priv->allpassR[i], out_r1);
    }

    /* Remove the DC offset */
    out_l1 -= DC_OFFSET;
    out_r1 -= DC_OFFSET;

    /* Calculate output */
    out_l2 = out_l1 * priv->wet1 + out_r1 * priv->wet2 + input_2l * priv->dry;
    out_r2 = out_r1 * priv->wet1 + out_l1 * priv->wet2 + input_2r * priv->dry;
    *odata++ = (gint16) CLAMP (out_l2, G_MININT16, G_MAXINT16);
    *odata++ = (gint16) CLAMP (out_r2, G_MININT16, G_MAXINT16);

    if (abs (out_l2) > 0 || abs (out_r2) > 0)
      drained = FALSE;
  }
  return drained;
}

static gboolean
gst_freeverb_transform_m2s_float (GstFreeverb * filter,
    gfloat * idata, gfloat * odata, guint num_samples)
{
  GstFreeverbPrivate *priv = filter->priv;
  gint i, k;
  gfloat out_l1, out_r1, input_1;
  gfloat out_l2, out_r2, input_2;
  gboolean drained = TRUE;

  for (k = 0; k < num_samples; k++) {

    out_l1 = out_r1 = 0.0;

    /* The original Freeverb code expects a stereo signal and 'input_1'
     * is set to the sum of the left and right input_1 sample. Since
     * this code works on a mono signal, 'input_1' is set to twice the
     * input_1 sample. */
    input_2 = *idata++;
    input_1 = (2.0f * input_2 + DC_OFFSET) * priv->gain;

    /* Accumulate comb filters in parallel */
    for (i = 0; i < numcombs; i++) {
      freeverb_comb_process (priv->combL[i], input_1, out_l1);
      freeverb_comb_process (priv->combR[i], input_1, out_r1);
    }
    /* Feed through allpasses in series */
    for (i = 0; i < numallpasses; i++) {
      freeverb_allpass_process (priv->allpassL[i], out_l1);
      freeverb_allpass_process (priv->allpassR[i], out_r1);
    }

    /* Remove the DC offset */
    out_l1 -= DC_OFFSET;
    out_r1 -= DC_OFFSET;

    /* Calculate output */
    out_l2 = out_l1 * priv->wet1 + out_r1 * priv->wet2 + input_2 * priv->dry;
    out_r2 = out_r1 * priv->wet1 + out_l1 * priv->wet2 + input_2 * priv->dry;
    *odata++ = out_l2;
    *odata++ = out_r2;

    if (fabs (out_l2) > 0 || fabs (out_r2) > 0)
      drained = FALSE;
  }
  return drained;
}

static gboolean
gst_freeverb_transform_s2s_float (GstFreeverb * filter,
    gfloat * idata, gfloat * odata, guint num_samples)
{
  GstFreeverbPrivate *priv = filter->priv;
  gint i, k;
  gfloat out_l1, out_r1, input_1l, input_1r;
  gfloat out_l2, out_r2, input_2l, input_2r;
  gboolean drained = TRUE;

  for (k = 0; k < num_samples; k++) {

    out_l1 = out_r1 = 0.0;

    input_2l = *idata++;
    input_2r = *idata++;
    input_1l = (input_2l + DC_OFFSET) * priv->gain;
    input_1r = (input_2r + DC_OFFSET) * priv->gain;

    /* Accumulate comb filters in parallel */
    for (i = 0; i < numcombs; i++) {
      freeverb_comb_process (priv->combL[i], input_1l, out_l1);
      freeverb_comb_process (priv->combR[i], input_1r, out_r1);
    }
    /* Feed through allpasses in series */
    for (i = 0; i < numallpasses; i++) {
      freeverb_allpass_process (priv->allpassL[i], out_l1);
      freeverb_allpass_process (priv->allpassR[i], out_r1);
    }

    /* Remove the DC offset */
    out_l1 -= DC_OFFSET;
    out_r1 -= DC_OFFSET;

    /* Calculate output */
    out_l2 = out_l1 * priv->wet1 + out_r1 * priv->wet2 + input_2l * priv->dry;
    out_r2 = out_r1 * priv->wet1 + out_l1 * priv->wet2 + input_2r * priv->dry;
    *odata++ = out_l2;
    *odata++ = out_r2;

    if (fabs (out_l2) > 0 || fabs (out_r2) > 0)
      drained = FALSE;
  }
  return drained;
}

/* this function does the actual processing
 */
static GstFlowReturn
gst_freeverb_transform (GstBaseTransform * base, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  GstFreeverb *filter = GST_FREEVERB (base);
  guint num_samples = GST_BUFFER_SIZE (outbuf) / (2 * filter->width);
  GstClockTime timestamp;

  timestamp = GST_BUFFER_TIMESTAMP (inbuf);
  timestamp =
      gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (filter, "processing %u samples at %" GST_TIME_FORMAT,
      num_samples, GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (timestamp))
    gst_object_sync_values (G_OBJECT (filter), timestamp);

  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DISCONT))) {
    filter->drained = FALSE;
  }
  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP))) {
    if (filter->drained) {
      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
      memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf));
      return GST_FLOW_OK;
    }
  } else {
    filter->drained = FALSE;
  }

  filter->drained = filter->process (filter, GST_BUFFER_DATA (inbuf),
      GST_BUFFER_DATA (outbuf), num_samples);

  if (filter->drained) {
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
  }

  return GST_FLOW_OK;
}


static gboolean
plugin_init (GstPlugin * plugin)
{
  gst_controller_init (NULL, NULL);

  return gst_element_register (plugin, "freeverb",
      GST_RANK_NONE, GST_TYPE_FREEVERB);
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    freeverb,
    "Reverberation/room effect",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
