/* GStreamer
 * Copyright (C) <2004> Benjamin Otte <otte@gnome.org>
 *               <2007> Stefan Kost <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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-equalizer-nbands
 *
 * The n-band equalizer element is a fully parametric equalizer. It allows to
 * select between 1 and 64 bands and has properties on each band to change
 * the center frequency, band width and gain.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 filesrc location=song.ogg ! oggdemux ! vorbisdec ! audioconvert ! equalizer-nbands num-bands=15 band5::gain=6.0 ! alsasink
 * ]| This make the equalizer use 15 bands and raises the volume of the 5th band by 6 db.
 * </refsect2>
 * <refsect2>
 * <title>Example code</title>
 * |[
 * #include &lt;gst/gst.h&gt;
 * 
 * ...
 * typedef struct {
 *   gfloat freq;
 *   gfloat width;
 *   gfloat gain;
 * } GstEqualizerBandState;
 * 
 * ...
 * 
 *   GstElement *equalizer;
 *   GObject *band;
 *   gint i;
 *   GstEqualizerBandState state[] = {
 *     { 120.0,   50.0, - 3.0},
 *     { 500.0,   20.0,  12.0},
 *     {1503.0,    2.0, -20.0},
 *     {6000.0, 1000.0,   6.0},
 *     {3000.0,  120.0,   2.0}
 *   };
 * 
 * ...
 * 
 *   equalizer = gst_element_factory_make ("equalizer-nbands", "equalizer");
 *   g_object_set (G_OBJECT (equalizer), "num-bands", 5, NULL);
 * 
 * ...
 * 
 *   for (i = 0; i &lt; 5; i++) {
 *     band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (equalizer), i);
 *     g_object_set (G_OBJECT (band), "freq", state[i].freq,
 *         "bandwidth", state[i].width,
 * 	"gain", state[i].gain);
 *     g_object_unref (G_OBJECT (band));
 *   }
 * 
 * ...
 * ]|
 * </refsect2>
 */

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

#include "gstiirequalizer.h"
#include "gstiirequalizernbands.h"


enum
{
  PROP_NUM_BANDS = 1
};

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

GST_DEBUG_CATEGORY_EXTERN (equalizer_debug);
#define GST_CAT_DEFAULT equalizer_debug

#define gst_iir_equalizer_nbands_parent_class parent_class
G_DEFINE_TYPE (GstIirEqualizerNBands, gst_iir_equalizer_nbands,
    GST_TYPE_IIR_EQUALIZER);

/* equalizer implementation */

static void
gst_iir_equalizer_nbands_class_init (GstIirEqualizerNBandsClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;

  gobject_class->set_property = gst_iir_equalizer_nbands_set_property;
  gobject_class->get_property = gst_iir_equalizer_nbands_get_property;

  g_object_class_install_property (gobject_class, PROP_NUM_BANDS,
      g_param_spec_uint ("num-bands", "num-bands",
          "number of different bands to use", 1, 64, 10,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));

  gst_element_class_set_static_metadata (gstelement_class, "N Band Equalizer",
      "Filter/Effect/Audio",
      "Direct Form IIR equalizer",
      "Benjamin Otte <otte@gnome.org>," " Stefan Kost <ensonic@users.sf.net>");
}

static void
gst_iir_equalizer_nbands_init (GstIirEqualizerNBands * equ_n)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (equ_n);

  gst_iir_equalizer_compute_frequencies (equ, 10);
}

static void
gst_iir_equalizer_nbands_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (object);

  switch (prop_id) {
    case PROP_NUM_BANDS:
      gst_iir_equalizer_compute_frequencies (equ, g_value_get_uint (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_iir_equalizer_nbands_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstIirEqualizer *equ = GST_IIR_EQUALIZER (object);

  switch (prop_id) {
    case PROP_NUM_BANDS:
      g_value_set_uint (value, equ->freq_band_count);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
