/* 
 * GStreamer
 * Copyright (C) 2008 Wim Taymans <wim.taymans@gmail.com>
 *
 * 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-audiokaraoke
 *
 * Remove the voice from audio by filtering the center channel.
 * This plugin is useful for karaoke applications.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 filesrc location=song.ogg ! oggdemux ! vorbisdec ! audiokaraoke ! audioconvert ! alsasink
 * ]|
 * </refsect2>
 */

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

#include <math.h>

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

#include "audiokaraoke.h"

#define GST_CAT_DEFAULT gst_audio_karaoke_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

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

#define DEFAULT_LEVEL		1.0
#define DEFAULT_MONO_LEVEL	1.0
#define DEFAULT_FILTER_BAND	220.0
#define DEFAULT_FILTER_WIDTH	100.0

enum
{
  PROP_0,
  PROP_LEVEL,
  PROP_MONO_LEVEL,
  PROP_FILTER_BAND,
  PROP_FILTER_WIDTH,
  PROP_LAST
};

#define ALLOWED_CAPS \
    "audio/x-raw,"                                                \
    " format=(string){"GST_AUDIO_NE(S16)","GST_AUDIO_NE(F32)"},"  \
    " rate=(int)[1,MAX],"                                         \
    " channels=(int)2,"                                           \
    " channel-mask=(bitmask)0x3,"                                 \
    " layout=(string) interleaved"

G_DEFINE_TYPE (GstAudioKaraoke, gst_audio_karaoke, GST_TYPE_AUDIO_FILTER);

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

static gboolean gst_audio_karaoke_setup (GstAudioFilter * filter,
    const GstAudioInfo * info);
static GstFlowReturn gst_audio_karaoke_transform_ip (GstBaseTransform * base,
    GstBuffer * buf);

static void gst_audio_karaoke_transform_int (GstAudioKaraoke * filter,
    gint16 * data, guint num_samples);
static void gst_audio_karaoke_transform_float (GstAudioKaraoke * filter,
    gfloat * data, guint num_samples);

/* GObject vmethod implementations */

static void
gst_audio_karaoke_class_init (GstAudioKaraokeClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstCaps *caps;

  GST_DEBUG_CATEGORY_INIT (gst_audio_karaoke_debug, "audiokaraoke", 0,
      "audiokaraoke element");

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

  gobject_class->set_property = gst_audio_karaoke_set_property;
  gobject_class->get_property = gst_audio_karaoke_get_property;

  g_object_class_install_property (gobject_class, PROP_LEVEL,
      g_param_spec_float ("level", "Level",
          "Level of the effect (1.0 = full)", 0.0, 1.0, DEFAULT_LEVEL,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_MONO_LEVEL,
      g_param_spec_float ("mono-level", "Mono Level",
          "Level of the mono channel (1.0 = full)", 0.0, 1.0, DEFAULT_LEVEL,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_FILTER_BAND,
      g_param_spec_float ("filter-band", "Filter Band",
          "The Frequency band of the filter", 0.0, 441.0, DEFAULT_FILTER_BAND,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_FILTER_WIDTH,
      g_param_spec_float ("filter-width", "Filter Width",
          "The Frequency width of the filter", 0.0, 100.0, DEFAULT_FILTER_WIDTH,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (gstelement_class, "AudioKaraoke",
      "Filter/Effect/Audio",
      "Removes voice from sound", "Wim Taymans <wim.taymans@gmail.com>");

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

  GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
      GST_DEBUG_FUNCPTR (gst_audio_karaoke_transform_ip);
  GST_BASE_TRANSFORM_CLASS (klass)->transform_ip_on_passthrough = FALSE;

  GST_AUDIO_FILTER_CLASS (klass)->setup =
      GST_DEBUG_FUNCPTR (gst_audio_karaoke_setup);
}

static void
gst_audio_karaoke_init (GstAudioKaraoke * filter)
{
  gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
  gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);

  filter->level = DEFAULT_LEVEL;
  filter->mono_level = DEFAULT_MONO_LEVEL;
  filter->filter_band = DEFAULT_FILTER_BAND;
  filter->filter_width = DEFAULT_FILTER_WIDTH;
}

static void
update_filter (GstAudioKaraoke * filter, const GstAudioInfo * info)
{
  gfloat A, B, C;
  gint rate;

  if (info) {
    rate = GST_AUDIO_INFO_RATE (info);
  } else {
    rate = GST_AUDIO_FILTER_RATE (filter);
  }

  if (rate == 0)
    return;

  C = exp (-2 * G_PI * filter->filter_width / rate);
  B = -4 * C / (1 + C) * cos (2 * G_PI * filter->filter_band / rate);
  A = sqrt (1 - B * B / (4 * C)) * (1 - C);

  filter->A = A;
  filter->B = B;
  filter->C = C;
  filter->y1 = 0.0;
  filter->y2 = 0.0;
}

static void
gst_audio_karaoke_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioKaraoke *filter;

  filter = GST_AUDIO_KARAOKE (object);

  switch (prop_id) {
    case PROP_LEVEL:
      filter->level = g_value_get_float (value);
      break;
    case PROP_MONO_LEVEL:
      filter->mono_level = g_value_get_float (value);
      break;
    case PROP_FILTER_BAND:
      filter->filter_band = g_value_get_float (value);
      update_filter (filter, NULL);
      break;
    case PROP_FILTER_WIDTH:
      filter->filter_width = g_value_get_float (value);
      update_filter (filter, NULL);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_audio_karaoke_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioKaraoke *filter;

  filter = GST_AUDIO_KARAOKE (object);

  switch (prop_id) {
    case PROP_LEVEL:
      g_value_set_float (value, filter->level);
      break;
    case PROP_MONO_LEVEL:
      g_value_set_float (value, filter->mono_level);
      break;
    case PROP_FILTER_BAND:
      g_value_set_float (value, filter->filter_band);
      break;
    case PROP_FILTER_WIDTH:
      g_value_set_float (value, filter->filter_width);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* GstAudioFilter vmethod implementations */

static gboolean
gst_audio_karaoke_setup (GstAudioFilter * base, const GstAudioInfo * info)
{
  GstAudioKaraoke *filter = GST_AUDIO_KARAOKE (base);
  gboolean ret = TRUE;

  switch (GST_AUDIO_INFO_FORMAT (info)) {
    case GST_AUDIO_FORMAT_S16:
      filter->process = (GstAudioKaraokeProcessFunc)
          gst_audio_karaoke_transform_int;
      break;
    case GST_AUDIO_FORMAT_F32:
      filter->process = (GstAudioKaraokeProcessFunc)
          gst_audio_karaoke_transform_float;
      break;
    default:
      ret = FALSE;
      break;
  }
  update_filter (filter, info);

  return ret;
}

static void
gst_audio_karaoke_transform_int (GstAudioKaraoke * filter,
    gint16 * data, guint num_samples)
{
  gint i, l, r, o, x;
  gint channels;
  gdouble y;
  gint level;

  channels = GST_AUDIO_FILTER_CHANNELS (filter);
  level = filter->level * 256;

  for (i = 0; i < num_samples; i += channels) {
    /* get left and right inputs */
    l = data[i];
    r = data[i + 1];
    /* do filtering */
    x = (l + r) / 2;
    y = (filter->A * x - filter->B * filter->y1) - filter->C * filter->y2;
    filter->y2 = filter->y1;
    filter->y1 = y;
    /* filter mono signal */
    o = (int) (y * filter->mono_level);
    o = CLAMP (o, G_MININT16, G_MAXINT16);
    o = (o * level) >> 8;
    /* now cut the center */
    x = l - ((r * level) >> 8) + o;
    r = r - ((l * level) >> 8) + o;
    data[i] = CLAMP (x, G_MININT16, G_MAXINT16);
    data[i + 1] = CLAMP (r, G_MININT16, G_MAXINT16);
  }
}

static void
gst_audio_karaoke_transform_float (GstAudioKaraoke * filter,
    gfloat * data, guint num_samples)
{
  gint i;
  gint channels;
  gdouble l, r, o;
  gdouble y;

  channels = GST_AUDIO_FILTER_CHANNELS (filter);

  for (i = 0; i < num_samples; i += channels) {
    /* get left and right inputs */
    l = data[i];
    r = data[i + 1];
    /* do filtering */
    y = (filter->A * ((l + r) / 2.0) - filter->B * filter->y1) -
        filter->C * filter->y2;
    filter->y2 = filter->y1;
    filter->y1 = y;
    /* filter mono signal */
    o = y * filter->mono_level * filter->level;
    /* now cut the center */
    data[i] = l - (r * filter->level) + o;
    data[i + 1] = r - (l * filter->level) + o;
  }
}

/* GstBaseTransform vmethod implementations */
static GstFlowReturn
gst_audio_karaoke_transform_ip (GstBaseTransform * base, GstBuffer * buf)
{
  GstAudioKaraoke *filter = GST_AUDIO_KARAOKE (base);
  guint num_samples;
  GstClockTime timestamp, stream_time;
  GstMapInfo map;

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

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

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

  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)))
    return GST_FLOW_OK;

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

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

  gst_buffer_unmap (buf, &map);

  return GST_FLOW_OK;
}
