/* 
 * GStreamer
 * Copyright (C) 2007-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.
 */

/* 
 * Chebyshev type 1 filter design based on
 * "The Scientist and Engineer's Guide to DSP", Chapter 20.
 * http://www.dspguide.com/
 *
 * For type 2 and Chebyshev filters in general read
 * http://en.wikipedia.org/wiki/Chebyshev_filter
 *
 * Transformation from lowpass to bandpass/bandreject:
 * http://docs.dewresearch.com/DspHelp/html/IDH_LinearSystems_LowpassToBandPassZ.htm
 * http://docs.dewresearch.com/DspHelp/html/IDH_LinearSystems_LowpassToBandStopZ.htm
 * 
 */

/**
 * SECTION:element-audiochebband
 *
 * Attenuates all frequencies outside (bandpass) or inside (bandreject) of a frequency
 * band. The number of poles and the ripple parameter control the rolloff.
 *
 * This element has the advantage over the windowed sinc bandpass and bandreject filter that it is
 * much faster and produces almost as good results. It's only disadvantages are the highly
 * non-linear phase and the slower rolloff compared to a windowed sinc filter with a large kernel.
 *
 * For type 1 the ripple parameter specifies how much ripple in dB is allowed in the passband, i.e.
 * some frequencies in the passband will be amplified by that value. A higher ripple value will allow
 * a faster rolloff.
 *
 * For type 2 the ripple parameter specifies the stopband attenuation. In the stopband the gain will
 * be at most this value. A lower ripple value will allow a faster rolloff.
 *
 * As a special case, a Chebyshev type 1 filter with no ripple is a Butterworth filter.
 *
 * <note>
 * Be warned that a too large number of poles can produce noise. The most poles are possible with
 * a cutoff frequency at a quarter of the sampling rate.
 * </note>
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 audiotestsrc freq=1500 ! audioconvert ! audiochebband mode=band-pass lower-frequency=1000 upper-frequency=6000 poles=4 ! audioconvert ! alsasink
 * gst-launch-1.0 filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audiochebband mode=band-reject lower-frequency=1000 upper-frequency=4000 ripple=0.2 ! audioconvert ! alsasink
 * gst-launch-1.0 audiotestsrc wave=white-noise ! audioconvert ! audiochebband mode=band-pass lower-frequency=1000 upper-frequency=4000 type=2 ! audioconvert ! alsasink
 * ]|
 * </refsect2>
 */

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

#include <string.h>

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

#include <math.h>

#include "math_compat.h"

#include "audiochebband.h"

#include "gst/glib-compat-private.h"

#define GST_CAT_DEFAULT gst_audio_cheb_band_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0,
  PROP_MODE,
  PROP_TYPE,
  PROP_LOWER_FREQUENCY,
  PROP_UPPER_FREQUENCY,
  PROP_RIPPLE,
  PROP_POLES
};

#define gst_audio_cheb_band_parent_class parent_class
G_DEFINE_TYPE (GstAudioChebBand, gst_audio_cheb_band,
    GST_TYPE_AUDIO_FX_BASE_IIR_FILTER);

static void gst_audio_cheb_band_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_audio_cheb_band_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_audio_cheb_band_finalize (GObject * object);

static gboolean gst_audio_cheb_band_setup (GstAudioFilter * filter,
    const GstAudioInfo * info);

enum
{
  MODE_BAND_PASS = 0,
  MODE_BAND_REJECT
};

#define GST_TYPE_AUDIO_CHEBYSHEV_FREQ_BAND_MODE (gst_audio_cheb_band_mode_get_type ())
static GType
gst_audio_cheb_band_mode_get_type (void)
{
  static GType gtype = 0;

  if (gtype == 0) {
    static const GEnumValue values[] = {
      {MODE_BAND_PASS, "Band pass (default)",
          "band-pass"},
      {MODE_BAND_REJECT, "Band reject",
          "band-reject"},
      {0, NULL, NULL}
    };

    gtype = g_enum_register_static ("GstAudioChebBandMode", values);
  }
  return gtype;
}

/* GObject vmethod implementations */

static void
gst_audio_cheb_band_class_init (GstAudioChebBandClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;
  GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;

  GST_DEBUG_CATEGORY_INIT (gst_audio_cheb_band_debug, "audiochebband", 0,
      "audiochebband element");

  gobject_class->set_property = gst_audio_cheb_band_set_property;
  gobject_class->get_property = gst_audio_cheb_band_get_property;
  gobject_class->finalize = gst_audio_cheb_band_finalize;

  g_object_class_install_property (gobject_class, PROP_MODE,
      g_param_spec_enum ("mode", "Mode",
          "Low pass or high pass mode", GST_TYPE_AUDIO_CHEBYSHEV_FREQ_BAND_MODE,
          MODE_BAND_PASS,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_TYPE,
      g_param_spec_int ("type", "Type", "Type of the chebychev filter", 1, 2, 1,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  /* FIXME: Don't use the complete possible range but restrict the upper boundary
   * so automatically generated UIs can use a slider without */
  g_object_class_install_property (gobject_class, PROP_LOWER_FREQUENCY,
      g_param_spec_float ("lower-frequency", "Lower frequency",
          "Start frequency of the band (Hz)", 0.0, 100000.0,
          0.0,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_UPPER_FREQUENCY,
      g_param_spec_float ("upper-frequency", "Upper frequency",
          "Stop frequency of the band (Hz)", 0.0, 100000.0, 0.0,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RIPPLE,
      g_param_spec_float ("ripple", "Ripple", "Amount of ripple (dB)", 0.0,
          200.0, 0.25,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
  /* FIXME: What to do about this upper boundary? With a frequencies near
   * rate/4 32 poles are completely possible, with frequencies very low
   * or very high 16 poles already produces only noise */
  g_object_class_install_property (gobject_class, PROP_POLES,
      g_param_spec_int ("poles", "Poles",
          "Number of poles to use, will be rounded up to the next multiply of four",
          4, 32, 4,
          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (gstelement_class,
      "Band pass & band reject filter", "Filter/Effect/Audio",
      "Chebyshev band pass and band reject filter",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_cheb_band_setup);
}

static void
gst_audio_cheb_band_init (GstAudioChebBand * filter)
{
  filter->lower_frequency = filter->upper_frequency = 0.0;
  filter->mode = MODE_BAND_PASS;
  filter->type = 1;
  filter->poles = 4;
  filter->ripple = 0.25;

  g_mutex_init (&filter->lock);
}

static void
generate_biquad_coefficients (GstAudioChebBand * filter,
    gint p, gint rate, gdouble * b0, gdouble * b1, gdouble * b2, gdouble * b3,
    gdouble * b4, gdouble * a1, gdouble * a2, gdouble * a3, gdouble * a4)
{
  gint np = filter->poles / 2;
  gdouble ripple = filter->ripple;

  /* pole location in s-plane */
  gdouble rp, ip;

  /* zero location in s-plane */
  gdouble iz = 0.0;

  /* transfer function coefficients for the z-plane */
  gdouble x0, x1, x2, y1, y2;
  gint type = filter->type;

  /* Calculate pole location for lowpass at frequency 1 */
  {
    gdouble angle = (G_PI / 2.0) * (2.0 * p - 1) / np;

    rp = -sin (angle);
    ip = cos (angle);
  }

  /* If we allow ripple, move the pole from the unit
   * circle to an ellipse and keep cutoff at frequency 1 */
  if (ripple > 0 && type == 1) {
    gdouble es, vx;

    es = sqrt (pow (10.0, ripple / 10.0) - 1.0);

    vx = (1.0 / np) * asinh (1.0 / es);
    rp = rp * sinh (vx);
    ip = ip * cosh (vx);
  } else if (type == 2) {
    gdouble es, vx;

    es = sqrt (pow (10.0, ripple / 10.0) - 1.0);
    vx = (1.0 / np) * asinh (es);
    rp = rp * sinh (vx);
    ip = ip * cosh (vx);
  }

  /* Calculate inverse of the pole location to move from
   * type I to type II */
  if (type == 2) {
    gdouble mag2 = rp * rp + ip * ip;

    rp /= mag2;
    ip /= mag2;
  }

  /* Calculate zero location for frequency 1 on the
   * unit circle for type 2 */
  if (type == 2) {
    gdouble angle = G_PI / (np * 2.0) + ((p - 1) * G_PI) / (np);
    gdouble mag2;

    iz = cos (angle);
    mag2 = iz * iz;
    iz /= mag2;
  }

  /* Convert from s-domain to z-domain by
   * using the bilinear Z-transform, i.e.
   * substitute s by (2/t)*((z-1)/(z+1))
   * with t = 2 * tan(0.5).
   */
  if (type == 1) {
    gdouble t, m, d;

    t = 2.0 * tan (0.5);
    m = rp * rp + ip * ip;
    d = 4.0 - 4.0 * rp * t + m * t * t;

    x0 = (t * t) / d;
    x1 = 2.0 * x0;
    x2 = x0;
    y1 = (8.0 - 2.0 * m * t * t) / d;
    y2 = (-4.0 - 4.0 * rp * t - m * t * t) / d;
  } else {
    gdouble t, m, d;

    t = 2.0 * tan (0.5);
    m = rp * rp + ip * ip;
    d = 4.0 - 4.0 * rp * t + m * t * t;

    x0 = (t * t * iz * iz + 4.0) / d;
    x1 = (-8.0 + 2.0 * iz * iz * t * t) / d;
    x2 = x0;
    y1 = (8.0 - 2.0 * m * t * t) / d;
    y2 = (-4.0 - 4.0 * rp * t - m * t * t) / d;
  }

  /* Convert from lowpass at frequency 1 to either bandpass
   * or band reject.
   *
   * For bandpass substitute z^(-1) with:
   *
   *   -2            -1
   * -z   + alpha * z   - beta
   * ----------------------------
   *         -2            -1
   * beta * z   - alpha * z   + 1
   *
   * alpha = (2*a*b)/(1+b)
   * beta = (b-1)/(b+1)
   * a = cos((w1 + w0)/2) / cos((w1 - w0)/2)
   * b = tan(1/2) * cot((w1 - w0)/2)
   *
   * For bandreject substitute z^(-1) with:
   * 
   *  -2            -1
   * z   - alpha * z   + beta
   * ----------------------------
   *         -2            -1
   * beta * z   - alpha * z   + 1
   *
   * alpha = (2*a)/(1+b)
   * beta = (1-b)/(1+b)
   * a = cos((w1 + w0)/2) / cos((w1 - w0)/2)
   * b = tan(1/2) * tan((w1 - w0)/2)
   *
   */
  {
    gdouble a, b, d;
    gdouble alpha, beta;
    gdouble w0 = 2.0 * G_PI * (filter->lower_frequency / rate);
    gdouble w1 = 2.0 * G_PI * (filter->upper_frequency / rate);

    if (filter->mode == MODE_BAND_PASS) {
      a = cos ((w1 + w0) / 2.0) / cos ((w1 - w0) / 2.0);
      b = tan (1.0 / 2.0) / tan ((w1 - w0) / 2.0);

      alpha = (2.0 * a * b) / (1.0 + b);
      beta = (b - 1.0) / (b + 1.0);

      d = 1.0 + beta * (y1 - beta * y2);

      *b0 = (x0 + beta * (-x1 + beta * x2)) / d;
      *b1 = (alpha * (-2.0 * x0 + x1 + beta * x1 - 2.0 * beta * x2)) / d;
      *b2 =
          (-x1 - beta * beta * x1 + 2.0 * beta * (x0 + x2) +
          alpha * alpha * (x0 - x1 + x2)) / d;
      *b3 = (alpha * (x1 + beta * (-2.0 * x0 + x1) - 2.0 * x2)) / d;
      *b4 = (beta * (beta * x0 - x1) + x2) / d;
      *a1 = (alpha * (2.0 + y1 + beta * y1 - 2.0 * beta * y2)) / d;
      *a2 =
          (-y1 - beta * beta * y1 - alpha * alpha * (1.0 + y1 - y2) +
          2.0 * beta * (-1.0 + y2)) / d;
      *a3 = (alpha * (y1 + beta * (2.0 + y1) - 2.0 * y2)) / d;
      *a4 = (-beta * beta - beta * y1 + y2) / d;
    } else {
      a = cos ((w1 + w0) / 2.0) / cos ((w1 - w0) / 2.0);
      b = tan (1.0 / 2.0) * tan ((w1 - w0) / 2.0);

      alpha = (2.0 * a) / (1.0 + b);
      beta = (1.0 - b) / (1.0 + b);

      d = -1.0 + beta * (beta * y2 + y1);

      *b0 = (-x0 - beta * x1 - beta * beta * x2) / d;
      *b1 = (alpha * (2.0 * x0 + x1 + beta * x1 + 2.0 * beta * x2)) / d;
      *b2 =
          (-x1 - beta * beta * x1 - 2.0 * beta * (x0 + x2) -
          alpha * alpha * (x0 + x1 + x2)) / d;
      *b3 = (alpha * (x1 + beta * (2.0 * x0 + x1) + 2.0 * x2)) / d;
      *b4 = (-beta * beta * x0 - beta * x1 - x2) / d;
      *a1 = (alpha * (-2.0 + y1 + beta * y1 + 2.0 * beta * y2)) / d;
      *a2 =
          -(y1 + beta * beta * y1 + 2.0 * beta * (-1.0 + y2) +
          alpha * alpha * (-1.0 + y1 + y2)) / d;
      *a3 = (alpha * (beta * (-2.0 + y1) + y1 + 2.0 * y2)) / d;
      *a4 = -(-beta * beta + beta * y1 + y2) / d;
    }
  }
}

static void
generate_coefficients (GstAudioChebBand * filter, const GstAudioInfo * info)
{
  gint rate;

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

  if (rate == 0) {
    gdouble *a = g_new0 (gdouble, 1);
    gdouble *b = g_new0 (gdouble, 1);

    a[0] = 1.0;
    b[0] = 1.0;
    gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
        (filter), a, 1, b, 1);
    GST_LOG_OBJECT (filter, "rate was not set yet");
    return;
  }

  if (filter->upper_frequency <= filter->lower_frequency) {
    gdouble *a = g_new0 (gdouble, 1);
    gdouble *b = g_new0 (gdouble, 1);

    a[0] = 1.0;
    b[0] = (filter->mode == MODE_BAND_PASS) ? 0.0 : 1.0;
    gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
        (filter), a, 1, b, 1);

    GST_LOG_OBJECT (filter, "frequency band had no or negative dimension");
    return;
  }

  if (filter->upper_frequency > rate / 2) {
    filter->upper_frequency = rate / 2;
    GST_LOG_OBJECT (filter, "clipped upper frequency to nyquist frequency");
  }

  if (filter->lower_frequency < 0.0) {
    filter->lower_frequency = 0.0;
    GST_LOG_OBJECT (filter, "clipped lower frequency to 0.0");
  }

  /* Calculate coefficients for the chebyshev filter */
  {
    gint np = filter->poles;
    gdouble *a, *b;
    gint i, p;

    a = g_new0 (gdouble, np + 5);
    b = g_new0 (gdouble, np + 5);

    /* Calculate transfer function coefficients */
    a[4] = 1.0;
    b[4] = 1.0;

    for (p = 1; p <= np / 4; p++) {
      gdouble b0, b1, b2, b3, b4, a1, a2, a3, a4;
      gdouble *ta = g_new0 (gdouble, np + 5);
      gdouble *tb = g_new0 (gdouble, np + 5);

      generate_biquad_coefficients (filter, p, rate,
          &b0, &b1, &b2, &b3, &b4, &a1, &a2, &a3, &a4);

      memcpy (ta, a, sizeof (gdouble) * (np + 5));
      memcpy (tb, b, sizeof (gdouble) * (np + 5));

      /* add the new coefficients for the new two poles
       * to the cascade by multiplication of the transfer
       * functions */
      for (i = 4; i < np + 5; i++) {
        b[i] =
            b0 * tb[i] + b1 * tb[i - 1] + b2 * tb[i - 2] + b3 * tb[i - 3] +
            b4 * tb[i - 4];
        a[i] =
            ta[i] - a1 * ta[i - 1] - a2 * ta[i - 2] - a3 * ta[i - 3] -
            a4 * ta[i - 4];
      }
      g_free (ta);
      g_free (tb);
    }

    /* Move coefficients to the beginning of the array to move from
     * the transfer function's coefficients to the difference
     * equation's coefficients */
    for (i = 0; i <= np; i++) {
      a[i] = a[i + 4];
      b[i] = b[i + 4];
    }

    /* Normalize to unity gain at frequency 0 and frequency
     * 0.5 for bandreject and unity gain at band center frequency
     * for bandpass */
    if (filter->mode == MODE_BAND_REJECT) {
      /* gain is sqrt(H(0)*H(0.5)) */

      gdouble gain1 =
          gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b, np + 1,
          1.0, 0.0);
      gdouble gain2 =
          gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b, np + 1,
          -1.0, 0.0);

      gain1 = sqrt (gain1 * gain2);

      for (i = 0; i <= np; i++) {
        b[i] /= gain1;
      }
    } else {
      /* gain is H(wc), wc = center frequency */

      gdouble w1 = 2.0 * G_PI * (filter->lower_frequency / rate);
      gdouble w2 = 2.0 * G_PI * (filter->upper_frequency / rate);
      gdouble w0 = (w2 + w1) / 2.0;
      gdouble zr = cos (w0), zi = sin (w0);
      gdouble gain =
          gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b, np + 1, zr,
          zi);

      for (i = 0; i <= np; i++) {
        b[i] /= gain;
      }
    }

    gst_audio_fx_base_iir_filter_set_coefficients (GST_AUDIO_FX_BASE_IIR_FILTER
        (filter), a, np + 1, b, np + 1);

    GST_LOG_OBJECT (filter,
        "Generated IIR coefficients for the Chebyshev filter");
    GST_LOG_OBJECT (filter,
        "mode: %s, type: %d, poles: %d, lower-frequency: %.2f Hz, upper-frequency: %.2f Hz, ripple: %.2f dB",
        (filter->mode == MODE_BAND_PASS) ? "band-pass" : "band-reject",
        filter->type, filter->poles, filter->lower_frequency,
        filter->upper_frequency, filter->ripple);

    GST_LOG_OBJECT (filter, "%.2f dB gain @ 0Hz",
        20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
                np + 1, 1.0, 0.0)));
    {
      gdouble w1 = 2.0 * G_PI * (filter->lower_frequency / rate);
      gdouble w2 = 2.0 * G_PI * (filter->upper_frequency / rate);
      gdouble w0 = (w2 + w1) / 2.0;
      gdouble zr, zi;

      zr = cos (w1);
      zi = sin (w1);
      GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
          20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1,
                  b, np + 1, zr, zi)), (int) filter->lower_frequency);
      zr = cos (w0);
      zi = sin (w0);
      GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
          20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1,
                  b, np + 1, zr, zi)),
          (int) ((filter->lower_frequency + filter->upper_frequency) / 2.0));
      zr = cos (w2);
      zi = sin (w2);
      GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
          20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1,
                  b, np + 1, zr, zi)), (int) filter->upper_frequency);
    }
    GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
        20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
                np + 1, -1.0, 0.0)), rate / 2);
  }
}

static void
gst_audio_cheb_band_finalize (GObject * object)
{
  GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (object);

  g_mutex_clear (&filter->lock);

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

static void
gst_audio_cheb_band_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (object);

  switch (prop_id) {
    case PROP_MODE:
      g_mutex_lock (&filter->lock);
      filter->mode = g_value_get_enum (value);
      generate_coefficients (filter, NULL);
      g_mutex_unlock (&filter->lock);
      break;
    case PROP_TYPE:
      g_mutex_lock (&filter->lock);
      filter->type = g_value_get_int (value);
      generate_coefficients (filter, NULL);
      g_mutex_unlock (&filter->lock);
      break;
    case PROP_LOWER_FREQUENCY:
      g_mutex_lock (&filter->lock);
      filter->lower_frequency = g_value_get_float (value);
      generate_coefficients (filter, NULL);
      g_mutex_unlock (&filter->lock);
      break;
    case PROP_UPPER_FREQUENCY:
      g_mutex_lock (&filter->lock);
      filter->upper_frequency = g_value_get_float (value);
      generate_coefficients (filter, NULL);
      g_mutex_unlock (&filter->lock);
      break;
    case PROP_RIPPLE:
      g_mutex_lock (&filter->lock);
      filter->ripple = g_value_get_float (value);
      generate_coefficients (filter, NULL);
      g_mutex_unlock (&filter->lock);
      break;
    case PROP_POLES:
      g_mutex_lock (&filter->lock);
      filter->poles = GST_ROUND_UP_4 (g_value_get_int (value));
      generate_coefficients (filter, NULL);
      g_mutex_unlock (&filter->lock);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_audio_cheb_band_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (object);

  switch (prop_id) {
    case PROP_MODE:
      g_value_set_enum (value, filter->mode);
      break;
    case PROP_TYPE:
      g_value_set_int (value, filter->type);
      break;
    case PROP_LOWER_FREQUENCY:
      g_value_set_float (value, filter->lower_frequency);
      break;
    case PROP_UPPER_FREQUENCY:
      g_value_set_float (value, filter->upper_frequency);
      break;
    case PROP_RIPPLE:
      g_value_set_float (value, filter->ripple);
      break;
    case PROP_POLES:
      g_value_set_int (value, filter->poles);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/* GstAudioFilter vmethod implementations */

static gboolean
gst_audio_cheb_band_setup (GstAudioFilter * base, const GstAudioInfo * info)
{
  GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (base);

  generate_coefficients (filter, info);

  return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, info);
}
